circular linked list&CLL(循环链表)
循环链表,和苯一样,一条蛇咬住了自己的尾巴。在 操作系统 给 进程 分配运行 资源 时,有体现。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 struct node 5 { 6 int data; 7 struct node * next; 8 }; 9 //插入动作,在头节点之前插入 10 void insert(struct node ** head_ref, int data) 11 { 12 struct node * new_node = (struct node *) malloc (sizeof(struct node)); 13 struct node * temp = (*head_ref); 14 new_node->data = data; 15 // 头尾相连 16 new_node->next = (*head_ref); 17 //判断链表是否为空,如果不为空,则要循环到最后一个节点,让最后一个节点的next指向新的头结点 18 if(NULL != (*head_ref)) 19 { 20 while(temp->next != (*head_ref)) 21 { 22 temp = temp->next; 23 } 24 temp->next = new_node; 25 } 26 else 27 { 28 //若链表为空链表,则将欲插入的节点的next指向他自己 29 new_node->next = new_node; 30 } 31 //将其指定为头结点 32 (*head_ref) = new_node; 33 } 34 //判断该链表是否为一个循环链表 35 int isCircular(struct node * head_ref) 36 { 37 if(NULL == head_ref) 38 { 39 return 1; 40 } 41 42 struct node * temp = head_ref->next; 43 44 while(temp != NULL && temp != head_ref) 45 { 46 temp = temp->next; 47 } 48 49 return (temp == head_ref) ? 1 : -1; 50 } 51 //打印循环链表,可以从任何一个位置打印,而单链表只能从头结点开始打印(不考虑位置关系的话) 52 void printCircularLinkedList(struct node * head_ref) 53 { 54 struct node * temp = head_ref; 55 56 if(NULL != head_ref) 57 { 58 do 59 { 60 printf("%d ", temp->data); 61 temp = temp->next; 62 } 63 while(temp != head_ref); 64 printf("\n"); 65 } 66 } 67 //手撕鬼子似的将循环链表撕裂,WOW,这里用到了单链表里返回链表中间元素的 方法之一 68 void splitList(struct node * head, struct node ** head1_ref, struct node ** head2_ref) 69 { 70 struct node * fast_pointer = head; 71 struct node * slow_pointer = head; 72 73 if(-1 == headIsNULL(head)) 74 { 75 printf("ERROR!"); 76 return ; 77 } 78 79 while(fast_pointer->next->next != head && fast_pointer->next != head) 80 { 81 fast_pointer = fast_pointer->next->next; 82 slow_pointer = slow_pointer->next; 83 } 84 //如果不是当前元素不是尾节点的话,而是倒数第二个节点 85 if(head == fast_pointer->next->next) 86 { 87 fast_pointer = fast_pointer->next; 88 } 89 //判断该链表是否只有一个节点 90 if(head->next != head) 91 { 92 (*head2_ref) = slow_pointer->next; 93 fast_pointer->next = slow_pointer->next; 94 } 95 (*head1_ref) = head; 96 slow_pointer->next = (*head1_ref); 97 } 98 //排序式插入节点 99 void sortInsert(struct node ** head_ref, struct node * new_node) 100 { 101 struct node * current = (*head_ref); 102 103 if(NULL == (*head_ref)) 104 { 105 new_node->next = new_node; 106 (*head_ref) = new_node; 107 } 108 //如果插入节点的data小于当前头节点的data 109 else if(current->data >= new_node->data) 110 { 111 while(current->next != (*head_ref)) 112 current = current->next; 113 114 current->next = new_node; 115 new_node->next = (*head_ref); 116 (*head_ref) = new_node; 117 } 118 else 119 { 120 //若插入节点data大于当前节点data,循环链表到一个大于当前插入节点data的节点 121 while(current->next != (*head_ref) && current->next->data < new_node->data) 122 { 123 current = current->next; 124 } 125 //新节点的next = 当前节点的下一个节点 126 new_node->next = current->next; 127 current->next = new_node; 128 } 129 } 130 //判断链表是否为空 131 int headIsNULL(struct node * head_ref) 132 { 133 return (NULL == head_ref)? -1 : 1; 134 } 135 int main(void) 136 { 137 struct node * head = NULL; 138 139 insert(&head, 0); 140 insert(&head, 1); 141 insert(&head, 3); 142 insert(&head, 4); 143 insert(&head, 5); 144 printCircularLinkedList(head); 145 struct node * firstList = NULL; 146 struct node * lastList = NULL; 147 splitList(head, &firstList, &lastList); 148 printCircularLinkedList(firstList); 149 printCircularLinkedList(lastList); 150 /*------------------------------------*/ 151 int array[] = {2, 5, 1, 0, 9, 10, 3}; 152 int arraySize = sizeof(array)/sizeof(int); 153 struct node * head_1 = NULL; 154 struct node * temp = NULL; 155 156 for(int i = 0; i < arraySize; i++) 157 { 158 temp = (struct node *) malloc (sizeof (struct node)); 159 temp->data = array[i]; 160 sortInsert(&head_1, temp); 161 } 162 printCircularLinkedList(head_1); 163 if(0 < isCircular(head)) 164 { 165 printf("\nThe linked list is circularLinked list!"); 166 } 167 else 168 { 169 printf("\nThe linked list isn`t circularLinked list!"); 170 } 171 return 0; 172 }
受益颇多