单向循环链表概念
简单来说,单向循环链表就是在单链表的基础上,将最后一个结点的next指针域指向头指针。
单链表的许多操作与单链表相同或相似,接下来,我将举几个有代表性的操作。
单向循环链表定义
#include<stdio.h>
#include<stdlib.h>
#define OK 1;
#define ERROR 0;
typedef int ElemType;
typedef struct Lnode {
ElemType data;
struct Lnode* next;
}Lnode;
typedef struct Lnode* Clist;
初始化
/* 初始化单向循环链表 */
int InitClist(Clist* L)
{
(*L) = (Clist)malloc(sizeof(Lnode));
(*L)->next = (*L);
return OK;
}
头插法
初始化后,适用于第一次插入及其他情况
/* 单向循环链表头插法 */
int Inserthead(Clist* L, ElemType i)
{
int j,data;
for (j = 0; j < i; j++)
{
Clist p = (Clist)malloc(sizeof(Lnode));
scanf("%d", &data);
p->data = data;
p->next = (*L)->next;
(*L)->next = p;
}
return OK;
}
尾插法
初始化后,适用于第一次插入及其他情况
/* 单向循环链表尾插法 */
int Inserttail(Clist* L, ElemType i)
{
int j,data;
Clist p = (Clist)malloc(sizeof(Lnode));
Clist tailplace ; //用于定位尾位置
for (j = 0; j < i; j++)
{
Clist p = (Clist)malloc(sizeof(Lnode));
scanf("%d", &data);
p->data = data;
//定位尾结点
for (tailplace = *L; tailplace->next != *L; tailplace = tailplace->next);
p->next = tailplace->next;
tailplace->next = p;
}
return OK;
}
合并两个单向链表
/* 两个单向循环链表的和并 */
int connect(Clist* L1, Clist* L2)
{
Clist p;
Clist rear1; //用于指向L1的尾结点
Clist rear2; //用于指向L2的尾结点
//定位尾结点
for (rear1 = *L1; rear1->next != *L1; rear1 = rear1->next);
for (rear2 = *L2; rear2->next != *L2; rear2 = rear2->next);
p = rear1->next; //p存表头结点
rear1->next = rear2->next->next; //L2表头连接到L1表尾
free(rear2->next); //释放L2表头结点
rear2->next = p; //将L2尾结点连接到L1
return OK;
}
打印
/* 打印链表 */
void prinfClist(Clist L)
{
Clist p = (Clist)malloc(sizeof(Lnode));
p = L->next;
while (p->next != L->next)
{
printf("* %d\n", p->data);
p = p->next;
}
}
全部代码
#define _CRT_SECURE_NO_WARNINGS 1 //VS不支持scanf(),需加上这一行
#include<stdio.h>
#include<stdlib.h>
#define OK 1;
#define ERROR 0;
typedef int ElemType;
typedef struct Lnode {
ElemType data;
struct Lnode* next;
}Lnode;
typedef struct Lnode* Clist;
int InitClist(Clist *L); //初始化单向循环链表
int Inserthead(Clist* L, ElemType i); //单向循环链表头插法
int Inserttail(Clist* L, ElemType i); //单向循环链表尾插法
int connect(Clist* L1, Clist* L2); //两个单向循环链表的和并
void prinfClist(Clist L); //打印链表
int main(void)
{
Clist Ta, Tb;
printf("InitClist Ta %d\n",InitClist(&Ta));
printf("InitClist Tb %d\n", InitClist(&Tb));
printf("Inserthead Ta %d\n",Inserthead(&Ta, 5));
printf("Inserttail Tb %d\n", Inserttail(&Tb, 5));
printf("connect %d\n", connect(&Ta, &Tb));
prinfClist(Ta);
return 0;
}
/* 初始化单向循环链表 */
int InitClist(Clist* L)
{
(*L) = (Clist)malloc(sizeof(Lnode));
(*L)->next = (*L);
return OK;
}
/* 单向循环链表头插法 */
int Inserthead(Clist* L, ElemType i)
{
int j,data;
for (j = 0; j < i; j++)
{
Clist p = (Clist)malloc(sizeof(Lnode));
scanf("%d", &data);
p->data = data;
p->next = (*L)->next;
(*L)->next = p;
}
return OK;
}
/* 单向循环链表尾插法 */
int Inserttail(Clist* L, ElemType i)
{
int j,data;
Clist p = (Clist)malloc(sizeof(Lnode));
Clist tailplace ; //用于定位尾位置
for (j = 0; j < i; j++)
{
Clist p = (Clist)malloc(sizeof(Lnode));
scanf("%d", &data);
p->data = data;
//定位尾结点
for (tailplace = *L; tailplace->next != *L; tailplace = tailplace->next);
p->next = tailplace->next;
tailplace->next = p;
}
return OK;
}
/* 两个单向循环链表的和并 */
int connect(Clist* L1, Clist* L2)
{
Clist p;
Clist rear1; //用于指向L1的尾结点
Clist rear2; //用于指向L2的尾结点
//定位尾结点
for (rear1 = *L1; rear1->next != *L1; rear1 = rear1->next);
for (rear2 = *L2; rear2->next != *L2; rear2 = rear2->next);
p = rear1->next; //p存表头结点
rear1->next = rear2->next->next; //L2表头连接到L1表尾
free(rear2->next); //释放L2表头结点
rear2->next = p; //将L2尾结点连接到L1
return OK;
}
/* 打印链表 */
void prinfClist(Clist L)
{
Clist p = (Clist)malloc(sizeof(Lnode));
p = L->next;
while (p->next != L->next)
{
printf("* %d\n", p->data);
p = p->next;
}
}