考研一轮仅带头循环链表实现含测试效果(王卓版)

书上比较浅显的给出尾结点合并链表,这种操作虽然简单但是对于初学者无法实现,下面先给出带头结点与头指针的循环单链表的实现含测试效果,内容包括最基本的:创建、清空、插入、遍历、删除,内容完整可运行,适合初学者收藏学习用。感谢各位读者的观看建议手捧“严书”。,一本正经把王卓老师b站课刷一遍.

1、 循环单链表的存储结构

定义它时,跟普通单链表一样。

typedef struct CircleNode{
    
    
    ElementType data; //结点数据
    struct CircleNode* next; //后继点指针
}CircleNode,*CircList,*CircListRear;

2、初始化循环单链表

这部分就是自己指向自己

void InitCList(CircList& first){
    
    
    //算法调用方式initCList(first),输入:循环单链表的表头指针first;
    first =  new CircleNode;
    if(!first) {
    
    
        cout << "malloc failed!" << endl;
        exit(ERROR);
    }
    first->next = first; //置空表
}

3、清空循环单链表

用一个指针指向下一个,然后用头指向下一个的下一个,然后释放,最后完美成功

void ClearCList(CircList &first){
    
    
    //输入循环单链表 表头指针first;
    //释放所有循环单链表的所有结点,仅保留头结点
    CircleNode*p;
    while(first->next != first){
    
     //当链表非空
        p = first->next; //释放首元结点
        first->next = p->next;
        free(p);
    }
}

4、循环单链表数据初始化

也就是一个普通的尾插法。与普通单链表尾插法类似,但不同的是新建结点的下一跳指向循环头结点。其余一样。

/*调用方式createCList(first,A,n)
 * 输入:空的循环单链表表头指针first
 * 输入:first,数组A,输入数据个数n,
 * 输出:创建起来的循环单链表first;
 * */
void CreateCList(CircList &first,ElementType A[],int n){
    
    
    InitCList(first);
    CircList r = first,s;
    for(int i=0;i<n;i++){
    
    
        s = new CircleNode;
        s->data = A[i];
        s->next = r->next;
        r->next = s;
        r = s;
    }
}

5、打印循环单链表

只要p->next不指向first一直打印就行了

/*
 * 算法调用方式PrintCList(first),
 * 输入:循环单链表头指针first;
 * 输出:输出循环单链表fist的所有结点的数据
 * */
void PrintCList(CircList &first){
    
    
    for(CircList p = first->next;p!=first;p=p->next){
    
    
        cout << p->data << " ";

    }
    printf("\n");
}

6、查找第i个结点

先对输入参数进行检验然后开始跳

/*功能:定位到第i个结点
 * 输入:循环单链表头指针first,制定结点序号i
 * 输出:成功返回头结点地址,pre返回前驱结点地址,失败返回表头地址,pre返回尾元地址
 * */
CircleNode* LocateC(CircList& first,int i,CircleNode *&pre){
    
    
    if(first->next == first || i<=0) return first;
    CircleNode*p = first->next;
    int cnt =1;
    pre = first;
    while(p!=first && cnt < i) {
    
    
        pre = p;
        p = p->next;
        cnt ++;
    }
    return p;
}

7、删除第i个结点

有了locate函数,删除跟普通单链表类似

/*
 * 功能:删除某结点的数据
 * 输入:循环单链表头指针first,制定结点序号i,
 * 输出:OK 成功 ERROR 失败
 * */
Status DeleteC(CircList& first,int i,ElementType &x){
    
    
    if(first->next == first || i<=0) return ERROR;
    CircList pre,p;
    p = LocateC(first,i,pre);
    if(p==first) return ERROR;
    pre->next = p->next;
    x = p->data;
    free(p);
    return OK;
}

8、在第i个结点插入某值

也是先定位,然后再插入,插入与普通单链表一样。

/*输入:循环单链表头指针first,指定循环结点头序号i,插入值x,
 * 输出:OK为成功,ERROR失败
 * */
Status InsertC(CircList &first,int i,ElementType x){
    
    
    if(i<=0) return ERROR;
    CircList s,pre,p;
    p = LocateC(first,i,pre);
    s = new CircleNode;
    s->data = x;
    s->next = p;
    pre->next = s;
    return OK;
}

测试效果

在这里插入图片描述

完整测试源码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 10
typedef int ElementType;
typedef int Status;
using namespace std;
typedef struct CircleNode{
    
    
    ElementType data; //结点数据
    struct CircleNode* next; //后继点指针
}CircleNode,*CircList,*CircListRear;
//带头指针和头结点的循环单链表的基本运算
void InitCList(CircList& first){
    
    
    //算法调用方式initCList(first),输入:循环单链表的表头指针first;
    first =  new CircleNode;
    if(!first) {
    
    
        cout << "malloc failed!" << endl;
        exit(ERROR);
    }
    first->next = first; //置空表
}

void ClearCList(CircList &first){
    
    
    //输入循环单链表 表头指针first;
    //释放所有循环单链表的所有结点,仅保留头结点
    CircleNode*p;
    while(first->next != first){
    
     //当链表非空
        p = first->next; //释放首元结点
        first->next = p->next;
        free(p);
    }
}

/*调用方式createCList(first,A,n)
 * 输入:空的循环单链表表头指针first
 * 输入:first,数组A,输入数据个数n,
 * 输出:创建起来的循环单链表first;
 * */
void CreateCList(CircList &first,ElementType A[],int n){
    
    
    InitCList(first);
    CircList r = first,s;
    for(int i=0;i<n;i++){
    
    
        s = new CircleNode;
        s->data = A[i];
        s->next = r->next;
        r->next = s;
        r = s;
    }
}
/*
 * 算法调用方式PrintCList(first),
 * 输入:循环单链表头指针first;
 * 输出:输出循环单链表fist的所有结点的数据
 * */
void PrintCList(CircList &first){
    
    
    for(CircList p = first->next;p!=first;p=p->next){
    
    
        cout << p->data << " ";

    }
    printf("\n");
}
/*功能:定位到第i个结点
 * 输入:循环单链表头指针first,制定结点序号i
 * 输出:成功返回头结点地址,pre返回前驱结点地址,失败返回表头地址,pre返回尾元地址
 * */
CircleNode* LocateC(CircList& first,int i,CircleNode *&pre){
    
    
    if(first->next == first || i<=0) return first;
    CircleNode*p = first->next;
    int cnt =1;
    pre = first;
    while(p!=first && cnt < i) {
    
    
        pre = p;
        p = p->next;
        cnt ++;
    }
    return p;
}
/*输入:循环单链表头指针first,指定循环结点头序号i,插入值x,
 * 输出:OK为成功,ERROR失败
 * */

Status InsertC(CircList &first,int i,ElementType x){
    
    
    if(i<=0) return ERROR;
    CircList s,pre,p;
    p = LocateC(first,i,pre);
    s = new CircleNode;
    s->data = x;
    s->next = p;
    pre->next = s;
    return OK;
}
/*
 * 功能:删除某结点的数据
 * 输入:循环单链表头指针first,制定结点序号i,
 * 输出:OK 成功 ERROR 失败
 * */
Status DeleteC(CircList& first,int i,ElementType &x){
    
    
    if(first->next == first || i<=0) return ERROR;
    CircList pre,p;
    p = LocateC(first,i,pre);
    if(p==first) return ERROR;
    pre->next = p->next;
    x = p->data;
    free(p);
    return OK;
}
int main(){
    
    
    //带头结点的循环链表进行测试
    CircList L;
    InitCList(L); //初始化带头结点的循环单链表
    if(L){
    
    
        cout << "Init success" << endl;
    }else{
    
    
        cout << "Init failed" << endl;
    }
    int A[5]={
    
    1,2,3,4,5};
    CreateCList(L,A,5);//讲数据尾插法带头结点的循环单链表
    PrintCList(L);//打印带头结点单链表
    ClearCList(L);//清空单链表
    cout << "Cleared print:" << endl; //清空打印
    PrintCList(L);//打印
    CreateCList(L,A,5);//插入元素
    InsertC(L,3,8);//在3的位置插入8
    cout << "after pos:3 insert 8" << endl;
    PrintCList(L);//打印
    ElementType  v;
    DeleteC(L,4,v);//删除第四号节点
    cout << "after delete pos:4---" << v << endl;//打印第四号结点数据
    PrintCList(L);//打印
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37149062/article/details/123588985