单链表+尾首相连
链表初始化//定义结点
typedef struct Node{
ElemType data;
struct Node *next;
}Node;
typedef struct Node * LinkList;
循环链表创建and 插入新的元素
/*
2种情况:① 第一次开始创建; ②已经创建,往里面新增数据
1. 判断是否第一次创建链表
YES->创建一个新结点,并使得新结点的next 指向自身; (*L)->next = (*L);
NO-> 找链表尾结点,将尾结点的next = 新结点. 新结点的next = (*L);
*/
int CreateList(LinkList *L){
int item;
LinkList temp,target;
printf("输入节点的值,输入0结束\n”);
// LinkList r = NULL; //尾插法
while(1) {
scanf("%d",&item);
if(item==0) break;
if(*L==NULL) { //如果输入的链表是空。则创建一个新的节点,
*L = (LinkList)malloc(sizeof(Node));
if(!L)exit(0);
(*L)->data=item;
(*L)->next=*L;//使其next指针指向自己 (*head)->next=*head;==>循环
//r = *L; // 标记尾巴
} else {
for (target = *L; target->next != *L; target = target->next);//寻找链表的尾节点
temp=(LinkList)malloc(sizeof(Node));
if(!temp) return ERROR;
temp->data=item;
temp->next=*L; //新节点指向头节点
target->next=temp;//尾节点指向新节点
//r = temp;
}
}
return 1;
}
遍历循环链表
//遍历循环链表,循环链表的遍历最好用do while语句,因为头节点就有值
void show(LinkList p) {
//如果链表是空
if(p == NULL){
printf("打印的链表为空!\n");
return;
}else{
LinkList temp = p;
do{
printf("%5d",temp->data);
temp = temp->next;
}while (temp != p);
printf("\n");
}
}
循环链表插入数据
//循环链表插入数据
int ListInsert(LinkList *L, int place, int num){
temp = (LinkList)malloc(sizeof(Node));//1. 创建新结点temp,并判断是否创建成功,成功则赋值,否则返回ERROR;
if (temp == NULL) {
return 0;
}
temp->data = num;
LinkList target;
if (place == 1) { //如果插入的位置为1,则属于插入首元结点,所以需要特殊处理
for (target = *L; target->next != *L; target = target->next);////2. 找到链表最后的结点_尾结点,
temp->next = *L;//3. 让新结点的next 执行头结点.
target->next = temp;//4. 尾结点的next 指向新的头结点;
*L = temp;//5. 让头指针指向temp(临时的新结点)
} else {
int i = 1;
for (target = *L; target->next != *L && i < place - 1; target = target->next,i++); //2. 先找到插入的位置,如果超过链表长度,则自动插入队尾;
temp->next = target->next;//3. 插入结点的前驱指向新结点,新结点的next 指向target原来的next位置 ;
target->next = temp;//4. 通过target找到要插入位置的前一个结点, 让target->next = temp;
}
return 1;
}
循环链表删除元素
//循环链表删除元素
int LinkListDelete1(LinkList *L,int place){
LinkList temp = *L;
if (temp == NULL) {
return 0;
}
LinkList target;
if (place == 1) {
if (temp->next == *L) {//如果删除到只剩下首元结点了,则直接将*L置空;
*L = NULL;
return 1;
}
for (target = *L; target->next != *L; target = target->next);//1. 找到尾结点,
*L = (*L)->next;//更换首节点
target->next = *L;//首尾相连
} else {
int i = 1;
for (target = *L; target->next != *L && i < place-1; target = target->next,i++);//1. 找到place-1 节点
temp = target->next;
target->next = temp->next;//使得target->next 指向下一个结点
}
free(temp);//释放
return 1;
}
//循环链表查询值 根据值查找对应位置。
int findValue(LinkList L,int value){
int i = 1;
LinkList p;
p = L;
//寻找链表中的结点 data == value
while (p->data != value && p->next != L) {
i++;
p = p->next;
}
//当尾结点指向头结点就会直接跳出循环,所以要额外增加一次判断尾结点的data == value;
if (p->next == L && p->data != value) {
return -1;
}
return i;
}