#ifndef CIRCULARLIST_H
#define CIRCULARLIST_H
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
typedef int ElemType;
// 循环链表节点
typedef struct CircularNode{
ElemType data;
struct CircularNode *next;
}*CircularList;
// 返回一个动态分配的新节点,该节点尾部指向头部(头结点不用于存放数据)
CircularList NewCircularListNode()
{
CircularList list = (CircularList)malloc(sizeof(struct CircularNode));
if (!list)
return NULL;
memset(list, 0, sizeof(struct CircularNode));
list->next = list;
return list;
}
void CircularListInfo(CircularList list)
{
CircularList pos = list; // 头结点
// 先遍历元素,再打印其值
printf("listhead=%p: ",list);
if (list->next == list) { // 只有头结点,没有有效数据
printf("list is null\n");
return;
}
pos = pos->next; // 第一个节点开始
while(pos != list){
printf("%d, ",pos->data);
pos = pos->next;
}
printf("\n");
}
// 在第i个节点前面插入新元素(有头结点)
int CircularListInsert(CircularList list, int i, ElemType e)
{
CircularList pos = list;
// head ==> head new
// head 1 3 ==> head 1 new 3 , i =2
// head 1 2 ==> head 1 2 new , i =3
/* 1.找到插入位置的前一个节点
* 2.分配新节点,将新节点插入到链表中
*/
for(int k=1; k <= i-1; k++) {
pos = pos->next;
if (pos == list) { // 插入位置超出链表长度
printf("insert location error\n");
return -1;
}
}
CircularList new = NewCircularListNode();
// pos为新插入位置的前一项
new->data = e;
new->next = pos->next; //新节点的next指向(插入位置前一项的后一项)
pos->next = new;
return 0;
}
// 删除第i个节点(有头结点)。
int CircularListDelete(CircularList list, int i)
{
CircularList pos = list;
/* 1.从链表中删除节点
* 2.释放节点空间
*/
if (list->next == list){ // 没有有效节点
return -1;
}
for(int k=1; k <= i-1; k++) {
pos = pos->next;
if (pos == list) { // 插入位置超出链表长度
printf("Delete location error\n");
return -1;
}
}
// pos是被删除节点的前一项
CircularList delete = pos->next; // 将被删除的节点
pos->next = delete->next;
free(delete);
return 0;
}
// 链表拼接 = list1 list2, 只保留list1的头结点。拼接完成后表2的结构已经被破坏。
/* p3
head1 p2
p1
p6
head2 p5
p4
步骤:
1.找到表1的尾结点
2.找到表2的尾结点
3.将表2中的所有非头结点组成的单链表插入到表1中
p6 p5 p4
head1
p1 p2 p3
4.释放表2的头结点
*/
int SpliceList(CircularList list1, CircularList list2)
{
CircularList listTail1 = list1->next; // 表1的尾结点
CircularList listTail2 = list2->next; // 表1的尾结点
//printf("list1=%p, list2=%p\n", list1, list2);
if (!list1 || !list2)
return -1;
// list2只有头结点,不用拼接.
if (listTail2 == list2)
return 0;
/* 1.找到表1的尾结点 */
while(1) {
if (listTail1->next == list1)
break;
listTail1 = listTail1->next;
//printf("listTail1=%p\n", listTail1);
}
/* 2.找到表2的尾结点 */
while(1) {
if (listTail2->next == list2)
break;
listTail2 = listTail2->next;
// printf("listTail2=%p\n", listTail2);
}
//printf("listTail1->next=%p, listTail2->next=%p\n", listTail1->next, listTail2->next);
/* 3.将表2中的所有非头结点组成的单链表插入到表1中 */
listTail1->next = list2->next;
listTail2->next = list1;
/* 4.释放表2的头结点 */
free(list2);
return 0;
}
#endif // CIRCULARLIST_H