上一篇咱們已經講過單鏈表,本篇給你們講解循單鏈表的一個變形是單向循環鏈表,鏈表中最後一個節點的next域再也不爲None,而是指向鏈表的頭節點,其基本操做和單鏈表思路同樣。node
經常使用的操做有python
class Node(): def __init__(self,num): self.element = num self.next = None class CricleLinkList(object): def __init__(self): self.head = None self.length = 0 # 一、判斷是否爲空 def is_empty(self): if self.head == None: return True else: return False # 二、頭部插入 def add(self, num): # 建立要插入的節點 node = Node(num) if self.is_empty()==True: # 若是爲空直接插入 self.head = node # 而且把自身的next執行頭結點 node.next = self.head else: # 將原來的頭結點做爲插入節點的next node.next = self.head current = self.head # 循壞找到最後一個節點 while current.next != self.head: current = current.next # 將最後一個節點的next執行插入節點 current.next = node # 將插入的節點設置爲頭結點,完成循壞閉合 self.head = node # 每次添加完成一次,長度加1 self.length += 1 # 三、遍歷 def travel(self): if self.is_empty() == True: print("你要遍歷的循環鏈表爲空") return print("你要遍歷的循環鏈表元素有:", end=" ") current = self.head # 先把第一個元素打印一下 print("%d " % current.element, end=" ") # 打印只有一個元素的時候,第一個元素打印不出來,因此先把第一個打印出來 while current.next != self.head: current = current.next print("%d " % current.element, end=" ") print("") # 四、尾部插入 def append(self,num): node = Node(num) if self.is_empty() == True: self.add(num) else: current = self.head while current.next != self.head: current = current.next node.next = self.head current.next = node # 每次添加完成一次,長度加1 self.length += 1 # 五、指定位置插入 def insertAtIndex(self,num,index): if index<=0 or index>self.length+1: print("你要插入的位置不對,請從新選擇位置") return elif self.is_empty() == True: self.add(num) elif index==1: self.add(num) elif index == self.length+1: self.append(num) else: current = self.head for i in range(index-2): current = current.next node = Node(num) node.next = current.next current.next = node # 每次添加完成一次,長度加1 self.length += 1 # 六、按索引刪除 def deleteByIndex(self,index): if index<=0 or index>self.length: print("你要插入的位置不對,請從新選擇位置") return elif self.is_empty() == True: print("你要刪除的鏈表爲空") return elif index == 1: current = self.head for i in range(1,self.length): current = current.next current.next = self.head.next self.head = self.head.next else: current = self.head for i in range(index-2): current = current.next current.next = current.next.next # 每次刪完長度減1 self.length -= 1 # 七、查找是否包含,並返回位置 def isContain(self,num): if self.is_empty() == True: print("你要查詢的鏈表爲空") return else: current = self.head for i in range(self.length): if current.element == num: print("你要找到元素在第%d個節點"%(i+1)) return i+1 current = current.next print("沒有找到你要的元素") return -1 # 八、根據下標找節點 def searchNodeByIndex(self,index): if index<=0 or index>self.length: print("你要查詢的位置不對,請從新選擇位置") return elif self.is_empty() == True: print("你要查詢的鏈表爲空") else: current = self.head for i in range(1,index): current = current.next print("你要查找%d位置上的節點的值是%d"%(index,current.element)) # 九、根據下標修改節點的值 def modifyByIndex(self,index,num): if index <= 0 or index > self.length: print("你要查詢的位置不對,請從新選擇位置") return elif self.is_empty() == True: print("你要修改的鏈表爲空") else: current = self.head for i in range(1, index): current = current.next current.element = num # 十、排序 def sort(self): if self.length<=0: return for i in (0,self.length-1): current = self.head for j in range(0,self.length-i-1): if current.element>current.next.element: temp = current.element current.element = current.next.element current.next.element = temp current = current.next if __name__ == '__main__': print("======一、建立循環鏈表 ======") cricle_link_list = CricleLinkList() print("======二、驗證是否爲空 ======") empty = cricle_link_list.is_empty() if empty == True: print("你查詢的鏈表爲空") else: print("你查詢的鏈表不爲空") print("\n======三、驗證頭插和遍歷 ======") cricle_link_list.add(1) cricle_link_list.travel() print("\n======四、繼續驗證頭插和遍歷 ======") cricle_link_list.add(2) cricle_link_list.travel() print("\n======五、驗證尾插 ======") cricle_link_list.append(3) cricle_link_list.travel() print("\n======六、驗證按位置插入 ======") cricle_link_list.insertAtIndex(0,2) cricle_link_list.travel() print("\n======七、驗證按位置刪除 ======") cricle_link_list.deleteByIndex(5) cricle_link_list.travel() print("\n======八、驗證查找是否包含元素 ======") cricle_link_list.isContain(2) print("\n======九、驗證根據下標查找元素 ======") cricle_link_list.searchNodeByIndex(3) print("\n======十、驗證修改 ======") cricle_link_list.modifyByIndex(3,5) cricle_link_list.travel() print("\n======十一、驗證排序 ======") cricle_link_list.sort() cricle_link_list.travel()
運行結果爲:app
======一、建立循環鏈表 ====== ======二、驗證是否爲空 ====== 你查詢的鏈表爲空 ======三、驗證頭插和遍歷 ====== 你要遍歷的循環鏈表元素有: 1 ======四、繼續驗證頭插和遍歷 ====== 你要遍歷的循環鏈表元素有: 2 1 ======五、驗證尾插 ====== 你要遍歷的循環鏈表元素有: 2 1 3 ======六、驗證按位置插入 ====== 你要遍歷的循環鏈表元素有: 2 0 1 3 ======七、驗證按位置刪除 ====== 你要插入的位置不對,請從新選擇位置 你要遍歷的循環鏈表元素有: 2 0 1 3 ======八、驗證查找是否包含元素 ====== 你要找到元素在第1個節點 ======九、驗證根據下標查找元素 ====== 你要查找3位置上的節點的值是1 ======十、驗證修改 ====== 你要遍歷的循環鏈表元素有: 2 0 5 3 ======十一、驗證排序 ====== 你要遍歷的循環鏈表元素有: 0 2 3 5
// // main.m // 循環鏈表 // // Created by 侯壘 on 2019/6/27. // Copyright © 2019 可愛的侯老師. All rights reserved. // #include <stdio.h> // 建立節點結構體 typedef struct N { int element; struct N *next; }Node; // 一、建立節點 Node *createNode(int num) { Node *node = (Node *)malloc(sizeof(Node)); node->element = num; node->next = NULL; return node; } // 二、建立循環鏈表 Node *createCricleLinkList(int num) { Node *head = createNode(num); head->next = head; return head; } // 三、判斷是否爲空 int is_empty(Node *head) { if (head == NULL) { return 1; } return 0; } //四、頭部插入 Node *add(Node *head,int num) { Node* node = createNode(num); Node *current = head; if (is_empty(head)==1) { head = node; node->next = head; } else { node->next = head; while (current->next != head) { current = current->next; } current->next = node; head = node; } return head; } // 五、遍歷 void travel(Node *head) { if (is_empty(head) == 1) { printf("你遍歷的鏈表爲空\n"); } else { printf("\n你要遍歷的循環鏈表元素有:"); Node *current = head; printf("%d ",current->element); while (current->next != head) { current = current->next; printf("%d ",current->element); } printf("\n"); } } // 五、尾部插入 Node *append(Node *head,int num) { Node *node = createNode(num); if (is_empty(head)==1) { add(head, num); } else { Node *current = head; while (current->next != head) { current = current->next; } node->next = head; current->next = node; } return head; } // 六、獲取鏈表長度 int getLength(Node *head) { int count = 1; Node *current = head; if (is_empty(head)==1) { return 0; } else { while (current->next !=head) { current = current->next; count++; } return count; } } // 七、根據下標插入節點 Node * insertByIndex(Node *head,int num,int index) { int len = getLength(head); if (index<=0||index>len+1) { printf("你要插入的位置不對,請從新選擇位置"); } else if (index == 1) { head = add(head, num); } else { Node *current = head; for (int i=1; i<index-1; i++) { current = current->next; } Node *node = createNode(num); node->next = current->next; current->next = node; } return head; } // 八、根據下標刪除 Node *deleteByIndex(Node *head,int index) { int len = getLength(head); if (index<=0||index>len) { printf("\n你要刪除的位置不對,請從新選擇位置"); } else if (index == 1) { Node *current = head; for (int i=1; i<len; i++) { current = current->next; } current->next = head->next; head = head->next; } else { Node *current = head; for (int i=0; i<index-2; i++) { current = current->next; } current->next = current->next->next; } return head; } // 九、查找是否包含,並返回位置 int isContain(Node *head,int num) { int len = getLength(head); Node *current = head; for (int i= 0; i<len; i++) { if (current->element == num) { return i+1; } current=current->next; } return 0; } // 十、根據下標找節點 Node *searchNodeByIndex(Node *head,int index) { Node *current = head; int len = getLength(head); if (index<=0||index>len) { printf("\n你要查詢的位置不對,請從新選擇位置"); } else { for (int i =1 ; i<index; i++) { current = current->next; } printf("\n你要查找的%d位置上的值爲%d",index,current->element); } return current; } // 十一、根據下標修改節點的值 void modefyByIndex(Node *head,int index,int num) { Node *current = head; int len = getLength(head); if (index<=0||index>len) { printf("\n你要修改的位置不對,請從新選擇位置"); } else { for (int i =1 ; i<index; i++) { current = current->next; } current->element = num; } } // 十二、排序 void sort(Node *head) { int len = getLength(head); if (len<=0) { return; } for (int i = 0; i<len-1; i++) { Node *current = head; for (int j=0; j<len-i-1; j++) { if (current->element >current->next->element) { int temp = current->element; current->element = current->next->element; current->next->element = temp; } current = current->next; } } } int main(int argc, const char * argv[]) { printf("=====一、建立循環鏈表====="); Node *head = createCricleLinkList(1); printf("\n=====二、驗證是否爲空=====\n"); int empty = is_empty(head); if (empty == 1) { printf("你建立的循環鏈表爲空"); } else { printf("你建立的循環鏈表不爲空"); } printf("\n=====三、驗證頭插和遍歷====="); travel(head); head = add(head, 0); travel(head); printf("\n=====四、驗證尾插====="); head = append(head, 2); travel(head); printf("\n=====五、驗證根據下表插入====="); head = insertByIndex(head, 3, 2); travel(head); printf("\n=====六、驗證根據下表刪除====="); head = deleteByIndex(head, 3); travel(head); printf("\n=====七、驗證是否包含====="); int num = 3; int index = isContain(head, num); if (index != 0) { printf("\n你查找的數據%d在第%d個位置",num,index); } else { printf("\n沒有找到你要的數據\n"); } printf("\n=====八、驗證根據下標找節點====="); searchNodeByIndex(head, 2); printf("\n=====九、驗證根據下標修改節點值====="); modefyByIndex(head,2,4); travel(head); printf("\n=====十、驗證排序====="); sort(head); travel(head); return 0; }
運行結果爲:spa
=====1、建立循環鏈表===== =====2、驗證是否爲空===== 你建立的循環鏈表不爲空 =====3、驗證頭插和遍歷===== 你要遍歷的循環鏈表元素有:1 你要遍歷的循環鏈表元素有:0 1 =====4、驗證尾插===== 你要遍歷的循環鏈表元素有:0 1 2 =====5、驗證根據下表插入===== 你要遍歷的循環鏈表元素有:0 3 1 2 =====6、驗證根據下表刪除===== 你要遍歷的循環鏈表元素有:0 3 2 =====7、驗證是否包含===== 你查找的數據3在第2個位置 =====8、驗證根據下標找節點===== 你要查找的2位置上的值爲3 =====9、驗證根據下標修改節點值===== 你要遍歷的循環鏈表元素有:0 4 2 =====10、驗證排序===== 你要遍歷的循環鏈表元素有:0 2 4