單鏈表的基本算法

鏈表與順序表的邏輯結構一致, 除了首尾節點/元素, 有一個直接前驅和后繼, 兩者物理結構不同, 鏈表由一個節點來存儲后繼節點的地址. 我相信面向對象語言中根據一個對象訪問其成員和父類等用的是同樣的存儲模式.

  • 類型定義
typedef struct Node {
    struct Node *pNext; // 指向后繼節點
    int data; // 數據域
}NODE,*PNODE;
  • 創建
PNODE creat_list() {
    PNODE pHead = (PNODE)(malloc(sizeof(NODE))); // 頭結點, 指向首節點, 其數據域為空
    if (NULL==pHead) {
        exit(-1);
    }
    int length;
    PNODE pNew;
    PNODE pEnd = (PNODE)(malloc(sizeof(NODE)));
    if (NULL==pEnd) {
        exit(-1);
    }
    pHead->data = 0;
    printf("請輸入長度:");
    scanf("%d",&length);
    pEnd = pHead;
 
    for (int i=0; i<length; i++) {
        int val;
        printf("請輸入:");
        scanf("%d",&val);
        pNew = (PNODE)(malloc(sizeof(NODE)));
        if (NULL==pNew) {
            exit(-1);
        }
        pNew->data = val;
        pNew->pNext = NULL;
        pEnd->pNext = pNew;
        pEnd = pNew;
    }
    return pHead;
}
  • 遍歷
void traverse_list(PNODE pHead)
{
    PNODE p = pHead->pNext;
    while (NULL != p) {
        printf("%d\n", p->data);
        p = p->pNext;
    }
    return;
}
  • 獲取長度
int length_list(PNODE pHead) {
    PNODE p = pHead->pNext;
    int length = 0; // 此處要初始化為0 不然就是1;
    while (NULL!=p) {
        ++length;
        p = p->pNext;
    }
    return length;
}
  • 判空
int is_empty(PNODE pHead) {
    if (NULL == pHead->pNext) {
        return 1;
    } else {
        return 0;
    }
}
  • 插入
int insert_list(PNODE pHead, int post, int val) {
    PNODE p = pHead;
    int i = 0;
    while (p && i < post-1) { // 這一步是為了找到第post-1個節點, 并p偏移到這個節點
        p = p->pNext;
        ++i;
    }
    // 此時p已經指向了第post-1個節點
    if (NULL==p->pNext || i>post-1) { // 條件1是當post特別大的時候, 條件2是當post<1的時候
        printf("插入位置不合法");
        return -1;
    }
    
    PNODE e = (PNODE)malloc(sizeof(NODE));
    e->data = val;
    e->pNext = p->pNext;
    p->pNext = e;
    return 1;
}
  • 冒泡排序
void sort_list(PNODE pHead) {
    int len = length_list(pHead);
    PNODE p;
    int i,j,t;
    for (i = len - 2 ; i >= 0; --i) {
        for (j = 0,p = pHead->pNext; j <= i; j++) {
            // 取出第j個
            if (p->data > p->pNext->data) {
                t = p->data;
                p->data = p->pNext->data;
                p->pNext->data = t;
            }
            p=p->pNext;
        }
    }
    return;
}

順序表和鏈表的存儲結構決定了各自的優劣.
查找: 順序表可以直接根據內存地址計算直接取得, 也就是用數組下標;鏈表則必須根據其已知節點指針一步步偏移取得, 其效率低于順序表.
存儲空間: 順序表必須預估一個初始內存大小, 在實際操作過程中內存大小可能需要改變,比較麻煩. 鏈表則不需要考慮.僅此一點就決定了鏈表的使用會比順序表會多一些.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容