線性表 - 循環(huán)鏈表

1.引子
單鏈表解決了從A 查找到E的過(guò)程,假設(shè)現(xiàn)在要求從E 查找到A,用時(shí)最短,
因?yàn)閱捂湵硎菃蜗虻模荒軓那巴螅瑹o(wú)法解決這個(gè)問(wèn)題。因此引出了循環(huán)鏈表。
思路圖
將單鏈表的終端結(jié)點(diǎn)的指針由空指針改為頭結(jié)點(diǎn),就使整個(gè)單鏈表形成一個(gè)環(huán)。
這種頭尾相接的單鏈表成為單循環(huán)鏈表,簡(jiǎn)稱循環(huán)鏈表

循環(huán)鏈表和單鏈表的主要差異就在于循環(huán)判斷條件上,原來(lái)是判斷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開(kāi)始 創(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;
}


/** 獲得鏈表的長(zhǎng)度 */
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è)過(guò)程需要借助一個(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);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容