1.引子
單鏈表解決了從A 查找到E的過程罕伯,假設(shè)現(xiàn)在要求從E 查找到A,用時(shí)最短汹粤,
因?yàn)閱捂湵硎菃蜗虻模荒軓那巴竺闾桑瑹o法解決這個(gè)問題总棵。因此引出了循環(huán)鏈表。
思路圖
將單鏈表的終端結(jié)點(diǎn)的指針由空指針改為頭結(jié)點(diǎn),就使整個(gè)單鏈表形成一個(gè)環(huán)粒督。
這種頭尾相接的單鏈表成為單循環(huán)鏈表,簡(jiǎn)稱循環(huán)鏈表
循環(huán)鏈表和單鏈表的主要差異就在于循環(huán)判斷條件上禽翼,原來是判斷p->next 是否為空坠陈,
現(xiàn)在則是p->next 不等于頭結(jié)點(diǎn)。則循環(huán)未結(jié)束
2.循環(huán)鏈表的使用
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct node {
ElemType data;
struct node *next;
} Node,*LinkList;
/** 初始化鏈表 next指向自身*/
void Init_circleList(LinkList *list) {
(*list) = (LinkList)malloc(sizeof(Node));
(*list)->next = *list;
}
/** 從1開始 創(chuàng)建n個(gè)數(shù)據(jù) */
void create_circlrList(LinkList list, int n) {
LinkList rear, s;
rear = list;
for (int i = 1; i <= n; i++) {
s = (LinkList) malloc(sizeof(Node));
s->data = I;
rear->next = s;
rear = s;
}
rear->next = list;
}
/** 獲得鏈表的長度 */
int get_circle_list_Length(LinkList list) {
LinkList headr = list->next;
int count =0;
while (headr != list) {
headr = headr->next;
count++;
}
return count;
}
/** 在某個(gè)位置插入某個(gè)元素*/
Status insert_circleList(LinkList list, int i, ElemType e) {
if (i < 0 ) {
return ERROR;
}
LinkList headr = list;
LinkList node = (LinkList)malloc(sizeof(Node));
node->data = e;
//區(qū)分中間插入 or 尾部插入 or 頭插
if (i == 0) {
node->next = headr->next;
headr->next = node;
} else if(i == get_circle_list_Length(list)+1) {
while (headr->next != list) {
headr = headr->next;
}
headr->next = node;
node->next = list;
} else {
for (int k = 1; k < i; k++) {
headr = headr->next;
}
node->next = headr->next;
headr->next = node;
}
return OK;
}
/** 刪除某一個(gè)元素 需要考慮頭捐康、尾仇矾、中間*/
Status delete_Node_circleList(LinkList list, int kill) {
LinkList header = list;
LinkList deleteNodel;
int currentAllCount = get_circle_list_Length(list);
if (kill > currentAllCount) {
return ERROR;
}
if (kill == 0) {
deleteNodel = header->next;
header->next = deleteNodel->next;
free(deleteNodel);
} else if (kill == currentAllCount) {
for (int i = 1; i < currentAllCount; i++) {
header = header->next;
}
deleteNodel = header->next;
header->next = deleteNodel->next;
free(deleteNodel);
} else {
for (int i = 1; i < kill; i++) {
header = header->next;
}
deleteNodel = header->next;
header->next = deleteNodel->next;
free(deleteNodel);
}
return OK;
}
/** 遍歷鏈表*/
void Iteretor_circleList(LinkList list) {
LinkList headr = list->next;
while (headr != list) {
printf("+++ current data is %d\n",headr->data);
headr = headr->next;
}
}
#pragma mark - 使用
void k_circleNodel(void) {
LinkList list;
Init_circleList(&list);
create_circlrList(list, 10);
Iteretor_circleList(list);
printf("\n\n");
insert_circleList(list, 4, 13);
Iteretor_circleList(list);
printf("\n\n");
delete_Node_circleList(list, 10);
Iteretor_circleList(list);
}
3.將兩個(gè)單鏈表合并成一個(gè)循環(huán)鏈表
兩個(gè)單鏈表
合并流程
整個(gè)過程需要借助一個(gè)指針作為臨時(shí)變量,并祛除一個(gè)的頭結(jié)點(diǎn)
1.p = rearA -> next; //保存A的頭結(jié)點(diǎn)
2.rearA->next = rearB->next-next;
//將本是指向B的第一個(gè)結(jié)點(diǎn)(不是頭結(jié)點(diǎn)) 賦值給rearA->next
3.rearB->next = p; //將原A表的頭結(jié)點(diǎn)賦值給rearB->next
4.free(p);