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