循环链表是一种特殊的链表结构。它与普通链表不同的地方在于,最后一个节点指向第一个节点,形成了一个环。这也就意味着,在循环链表中,每个节点都有前驱节点和后继节点。循环链表既可以向前遍历,也可以向后遍历。循环链表的应用场景主要是在需要循环处理数据的场合,例如游戏中的玩家列表、环形缓存等。
循环单链表的操作
基本代码:
- struct Node {
- int data;
- struct Node* next;
- };
-
- struct Node* head = NULL;//头指针
-
- int count = 0; //统计节点数量
-
- struct Node* new(int x) //新节点的建立
- {
- struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
- temp->data = x;
- temp->next = NULL;
- return temp;
- }
1、循环单链表的建立
头插法
- void headList(int x)
- {
- struct Node* temp = new(x);
- struct Node* header = head; //用header来代替头指针来遍历
- if (head == NULL) //链表为空
- {
- head = temp;
- temp->next = head;
- count++;
- return;
- }
- temp->next = head; //新节点指向head
- while (header->next != temp->next) //header移动到最后的节点
- header = header->next;
- header->next = temp; //header指向开头
- head = temp; //头指针更新
- count++;
- }
尾插法
- void lastList(int x)
- {
- struct Node* temp = new(x);
- struct Node* header = head;
- if (head == NULL)
- {
- head = temp;
- temp->next = head;
- count++;
- return;
- }
- while (header->next != head) //header移动到尾节点
- header = header->next;
- temp->next = header->next; //新节点指向头指针
- header->next = temp; //header指向新节点
- count++;
- }
2、链表的按位插入
插入时应注意插入位置为开头或结尾,应进行特殊处理。
- void Insert(int x, int data)
- {
- struct Node* temp = new(data);
- struct Node* header = head;
- if (x == 1) //插入位置为1
- {
- temp->next = head;
- while (header->next != temp->next) //header移动到最后节点
- header = header->next;
- header->next = temp; //header指向新节点
- head = temp; //head更新
- count++;
- return;
- }
- if (x == count) //插入位置为count
- {
- while(header->next != head) //移动到最后节点
- header = header->next;
- temp->next = header->next; //新节点指向开头
- header->next = temp; //header指向新节点
- count++;
- return;
- }
- if (x<1 || x>count) //判断插入位置是否非法
- {
- printf("error!");
- return;
- }
- for (int i = 1; i < x-1; i++) //header移动到插入位置前节点
- header = header->next;
- temp->next = header->next; //新节点指向header指向的节点
- header->next = temp; //header指向新节点
- count++;
- }
3、按位删除
注意删除节点位置为1时,应特殊处理;
- void delete(int x)
- {
- struct Node* header = head;
- if (x<1 || x>count) //判断删除位置是否合法
- {
- printf("error!\n");
- return;
- }
- if (head == NULL) //链表为空
- {
- printf("empty!\n");
- return;
- }
- if (x == 1) //删除节点位置为开头
- {
- while (header->next != head) //header移动到最后节点
- header = header->next;
- struct Node* A = head; //保存head节点
- head = head->next; //head移动
- printf("delete a number is %d\n", A->data); //打印
- header->next = head; //将header指向新的head
- free(A); //释放内存
- count--; //数量-1
- return;
- }
- for (int i = 1; i < x - 1; i++) //header移动到删除位置前节点
- header = header->next;
- struct Node* A = header->next; //保存删除节点地址
- header->next = A->next; // header指向删除节点的后节点
- printf("delete a number is %d\n", A->data);
- free(A);
- count--;
- }
完整代码:
- struct Node {
- int data;
- struct Node* next;
- };
-
- struct Node* head = NULL;//头指针
-
- int count = 0; //统计节点数量
-
- struct Node* new(int x) //新节点的建立
- {
- struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
- temp->data = x;
- temp->next = NULL;
- return temp;
- }
- //头插法
- void headList(int x)
- {
- struct Node* temp = new(x);
- struct Node* header = head; //用header来代替头指针来遍历
- if (head == NULL)
- {
- head = temp;
- temp->next = head;
- count++;
- return;
- }
- temp->next = head; //新节点指向head
- while (header->next != temp->next) //header移动到最后的节点
- header = header->next;
- header->next = temp; //header指向开头
- head = temp; //头指针更新
- count++;
- }
- //尾插法
- void lastList(int x)
- {
- struct Node* temp = new(x);
- struct Node* header = head;
- if (head == NULL)
- {
- head = temp;
- temp->next = head;
- count++;
- return;
- }
- while (header->next != head) //header移动到尾节点
- header = header->next;
- temp->next = header->next; //新节点指向头指针
- header->next = temp; //header指向新节点
- count++;
- }
-
- //按位插入
- void Insert(int x, int data)
- {
- struct Node* temp = new(data);
- struct Node* header = head;
- if (x == 1) //插入位置为1
- {
- temp->next = head;
- while (header->next != temp->next) //header移动到最后节点
- header = header->next;
- header->next = temp; //header指向新节点
- head = temp; //head更新
- count++;
- return;
- }
- if (x == count) //插入位置为count
- {
- while(header->next != head) //移动到最后节点
- header = header->next;
- temp->next = header->next; //新节点指向开头
- header->next = temp; //header指向新节点
- count++;
- return;
- }
- if (x<1 || x>count) //判断插入位置是否非法
- {
- printf("error!");
- return;
- }
- for (int i = 1; i < x-1; i++) //header移动到插入位置前节点
- header = header->next;
- temp->next = header->next; //新节点指向header指向的节点
- header->next = temp; //header指向新节点
- count++;
- }
- //删除
- void delete(int x)
- {
- struct Node* header = head;
- if (x<1 || x>count) //判断删除位置是否合法
- {
- printf("error!\n");
- return;
- }
- if (head == NULL) //链表为空
- {
- printf("empty!\n");
- return;
- }
- if (x == 1) //删除节点位置为开头
- {
- while (header->next != head) //header移动到最后节点
- header = header->next;
- struct Node* A = head; //保存head节点
- head = head->next; //head移动
- printf("delete a number is %d\n", A->data); //打印
- header->next = head; //将header指向新的head
- free(A); //释放内存
- count--; //数量-1
- return;
- }
- for (int i = 1; i < x - 1; i++) //header移动到删除位置前节点
- header = header->next;
- struct Node* A = header->next; //保存删除节点地址
- header->next = A->next; // header指向删除节点的后节点
- printf("delete a number is %d\n", A->data);
- free(A);
- count--;
- }
-
-
- void Print()
- {
- struct Node* header = head;
- for (int i = 0; i < 5; i++)
- {
- printf("%d ", header->data);
- header = header->next;
- }
- printf("\n");
- }
-
- int main()
- {
- lastList(3);
- lastList(5);
- lastList(2);
- lastList(4);
- Insert(1,8);
- Print();
- delete(1);
- Print();
- return 0;
- }
循环双链表的操作
基本代码:
- struct Node {
- int data;
- struct Node* left;
- struct Node* right;
- };
-
- struct Node* head = NULL;
-
- int count = 0;
-
- struct Node* new(int x)
- {
- struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
- temp->data = x;
- temp->left = NULL;
- temp->right = NULL;
- return temp;
- }
1、循环双链表的建立
头插法
- void headList(int x)
- {
- struct Node* temp = new(x);
- struct Node* header = head;
- if (head == NULL) //链表为空
- {
- head = temp;
- temp->right = head; //指向新节点
- temp->left = head; //指向新节点
- count++;
- return;
- }
- while (header->right != head) //header指向最后节点
- header = header->right;
- temp->right = head; //新节点右指针指向head
- head->left = temp; //head指向节点的左节点指向新节点
- temp->left = header; //新节点左指针指向header
- header->right = temp; //header右指针指向新节点
- head = temp; //头指针更新
- count++;
- }
尾插法
- void lastList(int x)
- {
- struct Node* header = head;
- struct Node* temp = new(x);
- if (head == NULL)
- {
- head = temp;
- temp->right = head;
- temp->left = temp;
- count++;
- return;
- }
- while (header->right != head) //header指向尾节点
- header = header->right;
- temp->right = header->right; //新节点右指针指向head
- head->left = temp; //head的左指针指向新节点
- header->right = temp; //header的右指针指向新节点
- temp->left = header; //新节点的左指针指向header
- count++;
- }
2、按位插入
应对插入位置为1的情况进行特殊处理;
-
- void Insert(int x, int data)
- {
- struct Node* header = head;
- struct Node* temp = new(data);
- if (head == NULL)
- {
- printf("error!/n");
- return;
- }
- if (x<1 || x>count)
- {
- printf("error!\n");
- return;
- }
- if (x == 1) //插入位置为开头
- {
- while (header->right != head) //移动到尾节点
- header = header->right;
- temp->right = head; //新节点的右指针指向头节点
- header->right = temp; //header的右指针指向新节点
- temp->left = header; //新节点的左指针指向尾节点
- head->left = temp; //头节点的左指针指向新节点
- head = temp; //头指针的更新
- count++;
- return;
- }
- for (int i = 1; i <= x - 1; i++)
- header = header->right;
- temp->right = header->right;
- header->right->left = temp;
- header->right = temp;
- temp->left = header;
- count++;
- }
3、按位删除
对删除位置为开头和删除位置为结尾的情况进行特殊处理;
- void delete(int x)
- {
- struct Node* header = head;
- if (x<1 || x>count)
- {
- printf("error!\n");
- return;
- }
- if (x == 1)
- {
- struct Node* A = head;
- head = head->right;
- head->left = A->left;
- A->left->right = head;
- free(A);
- count--;
- return;
- }
- if (x == count)
- {
- struct Node* A = head->left;
- header = A->left;
- header->right = head;
- head->left = header;
- free(A);
- count--;
- return;
- }
- for (int i = 1; i < x - 1; i++)
- header = header->right;
- struct Node* A = header->right;
- header->right = A->right;
- A->right->left = header;
- free(A);
- count--;
- }
4、遍历(打印)
- void Print()
- {
- int falg = 0;
- struct Node* header = head;
- while (header != head || falg == 0)
- {
- printf("%d ", header->data);
- if (header->right == head)
- {
- falg = 1;
- break;
- }
- header = header->right;
- }
- printf("\n");
- struct Node* last = header;
- while (header != last|| falg == 1)
- {
- printf("%d ", header->data);
- if (header->left == last)
- {
- falg = 0;
- break;
- }
- header = header->left;
- }
- printf("\n");
- }
完整代码:
- struct Node {
- int data;
- struct Node* left;
- struct Node* right;
- };
-
- struct Node* head = NULL;
-
- int count = 0;
-
- struct Node* new(int x)
- {
- struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
- temp->data = x;
- temp->left = NULL;
- temp->right = NULL;
- return temp;
- }
-
- //头插法
- void headList(int x)
- {
- struct Node* temp = new(x);
- struct Node* header = head;
- if (head == NULL) //链表为空
- {
- head = temp;
- temp->right = head; //指向新节点
- temp->left = head; //指向新节点
- count++;
- return;
- }
- while (header->right != head) //header指向最后节点
- header = header->right;
- temp->right = head; //新节点右指针指向head
- head->left = temp; //head指向节点的左节点指向新节点
- temp->left = header; //新节点左指针指向header
- header->right = temp; //header右指针指向新节点
- head = temp; //头指针更新
- count++;
- }
-
- //尾插法
- void lastList(int x)
- {
- struct Node* header = head;
- struct Node* temp = new(x);
- if (head == NULL)
- {
- head = temp;
- temp->right = head;
- temp->left = temp;
- count++;
- return;
- }
- while (header->right != head) //header指向尾节点
- header = header->right;
- temp->right = header->right; //新节点右指针指向head
- head->left = temp; //head的左指针指向新节点
- header->right = temp; //header的右指针指向新节点
- temp->left = header; //新节点的左指针指向header
- count++;
- }
-
- //按位插入
- void Insert(int x, int data)
- {
- struct Node* header = head;
- struct Node* temp = new(data);
- if (head == NULL)
- {
- printf("error!/n");
- return;
- }
- if (x<1 || x>count)
- {
- printf("error!\n");
- return;
- }
- if (x == 1) //插入位置为开头
- {
- while (header->right != head) //移动到尾节点
- header = header->right;
- temp->right = head; //新节点的右指针指向头节点
- header->right = temp; //header的右指针指向新节点
- temp->left = header; //新节点的左指针指向尾节点
- head->left = temp; //头节点的左指针指向新节点
- head = temp; //头指针的更新
- count++;
- return;
- }
- for (int i = 1; i <= x - 1; i++)
- header = header->right;
- temp->right = header->right;
- header->right->left = temp;
- header->right = temp;
- temp->left = header;
- count++;
- }
- //删除
- void delete(int x)
- {
- struct Node* header = head;
- if (x<1 || x>count)
- {
- printf("error!\n");
- return;
- }
- if (x == 1)
- {
- struct Node* A = head;
- head = head->right;
- head->left = A->left;
- A->left->right = head;
- free(A);
- count--;
- return;
- }
- if (x == count)
- {
- struct Node* A = head->left;
- header = A->left;
- header->right = head;
- head->left = header;
- free(A);
- count--;
- return;
- }
- for (int i = 1; i < x - 1; i++)
- header = header->right;
- struct Node* A = header->right;
- header->right = A->right;
- A->right->left = header;
- free(A);
- count--;
- }
- //打印
- void Print()
- {
- int falg = 0;
- struct Node* header = head;
- while (header != head || falg == 0)
- {
- printf("%d ", header->data);
- if (header->right == head)
- {
- falg = 1;
- break;
- }
- header = header->right;
- }
- printf("\n");
- struct Node* last = header;
- while (header != last|| falg == 1)
- {
- printf("%d ", header->data);
- if (header->left == last)
- {
- falg = 0;
- break;
- }
- header = header->left;
- }
- printf("\n");
- }
- int main()
- {
- lastList(3);
- lastList(5);
- lastList(8);
- lastList(9);
- lastList(4);
- Print();
- Insert(1, 88);
- Insert(6, 99);
- Print();
- delete(5);
- Print();
- return 0;
- }
链表章节完结!