​​​​​​​C語言實現單鏈表基本操作方法

存儲結構

typedef int dataType;//愛護據類型
typedef struct Node {
    DataType data;   // 結點數據
    struct Node *next; // 指向下一個結點的指針
} Node, *LinkList;

基本功能

  • 頭插法創建單鏈表void CreateListHead( LinkList &head)
  • 尾插法創建單鏈表void CreateListTail( LinkList &head)
  • 獲取指定位置的元素 int GetElement(LinkList head, int i, DataType &e)
  • 獲取指定元素的位置 int LocateElement(LinkList head, int e)
  • 在指定位置插入元素 int InsertList(LinkList head, int i, DataType e)
  • 刪除指定位置的元素 int DeleteList(LinkList head, int i, DataType &e)
  • 獲取單鏈表的長度 int LengthLinkList(LinkList head)
  • 合並兩個非遞減的單鏈表 void MergeList(LinkList La, LinkList Lb, LinkList &Lc)
  • 寂鏈表void Destroy( LinkList &L)
  • 遍歷打印單鏈表中的所有元素 void PrintList(LinkList head)

頭插法創建單鏈表

每次添加鏈的結點都能找到頭結點的第1號位置,所以創建單表中的元素的順序是輸入元素的逆序。 ​

/**
 * 頭插法創建單鏈表,輸入以-1結束
 */
void CreateListHead(LinkList &head) {
    DataType x;
    LinkList p;

    head = (LinkList)malloc(LEN);
    head->next = NULL;
    scanf("%d", &x);
    while (x != -1) {
        p = (LinkList)malloc(LEN);
        p->data = x;
        p->next = head->next; // 新增的結點指向頭結點的下一個結點
        head->next = p;  // 頭結點指向新增的結點
        scanf("%d", &x);
    }
}

尾插法創建單鏈表

每次新增的結點都放在單鏈表的後面,接下來和接下來的順序保持一致。 ​

/**
 * 尾插法創建單鏈表,輸入以-1結束
 */
void CreateListTail(LinkList &head) {
    LinkList p, q;
    DataType x;

    head = (LinkList)malloc(LEN);
    q = head;
  	scanf("%d", &x);
    while (x != -1) {
        p = (LinkList)malloc(LEN);
        p->data = x;
        q->next = p;
        q = p;
        scanf("%d", &x);
    }
    q->next = NULL;
}

獲取指定位置的元素

/**
 * 獲取指定位置的元素
 * @param head 指向單鏈表頭結點的指針(頭指針)
 * @param i 位置
 * @param e 用來存放對應位置的元素值
 * @return 0:獲取失敗;1:獲取成功
 */
int GetElement(LinkList head, int i, DataType &e) {
    LinkList p = head->next;
    int j = 1;

    while (p && j < i) { // 依次後移,直至為空或到達位置
        p = p->next;
        j++;
    }
    if (!p || j > i) { // p為空表示位置超過最大位置,j > i表示位置不合法(i < 1)
        return 0;
    }
    e = p->data;
    return 1;
}

在指定位置插入元素

/**
 * 在單鏈表插入元素到位置i
 * @param head 單鏈表的頭指針
 * @param i 插入位置
 * @param e 插入元素
 * @return 1:插入成功,0:插入失敗
 */
int InsertList(LinkList head, int i, DataType e) {
    LinkList p = head; // 從頭結點開始
    int j = 1;
    while (p && j < i) { // 找到插入位置的前一個結點
        p = p->next;
        j++;
    }
    if (!p || j > i) { // p為空或i < 1,插入位置不合法
        return 0;
    }
    LinkList q = (LinkList)malloc(LEN); // 創建新結點
    q->data = e;
    q->next = p->next; // 將新結點指向前一個結點的後一個結點
    p->next = q; // 前一個結點指向新結點
    // 執行上述兩個操作後,達到的效果是新結點插入到瞭前一個結點的後面
}

刪除指定位置的元素

/**
 * 刪除指定位置的元素
 * @param head
 * @param i 位置
 * @param e 被刪除的元素的值存放在e中
 * @return 1:刪除成功,0:刪除失敗
 */
int DeleteList(LinkList head, int i, DataType &e) {
    LinkList p = head;
    int j = 1;

    while (p && j < i) {  // 找到位置的前一個結點
        p = p->next;
        j++;
    }
    if (!p || j > i) {
        return 0;
    }
    LinkList s = p->next;
    e = s->data;
    p->next = s->next; // 改變前一個結點的指向,使其指向刪除結點的後一個結點
    free(s); 
    return 1;
}

獲取單鏈表的長度

/**
 * 獲取單鏈表的長度
 * @param head
 * @return 單鏈表的長度
 */
int LengthLinkList(LinkList head) {
    LinkList p = head->next;
    int count = 0;

    while (p) {
        count++;
        p = p->next;
    }
    return count;
}

合並兩個非遞減的單鏈表

合並兩個非遞減的單鏈,新鏈表仍然保持非遞減。 ​

/**
 * 合並兩個非遞減的單鏈表,新的鏈表仍然非遞減
 * @param La
 * @param Lb
 * @param Lc
 */
void MergeList(LinkList La, LinkList Lb, LinkList &Lc) {
    LinkList pa, pb, pc;
    pa = La->next;
    pb = Lb->next;
    pc = Lc = (LinkList)malloc(LEN);
    while (pa && pb) {
        if (pa->data <= pb->data) {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        } else {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa ? pa : pb;
    free(Lb);
}

晴鏈表

/**
 * 銷毀鏈表
 */
void Destroy(LinkList &L) {
    LinkList p, q;
    p = L;
    while (p) { // 遍歷所有結點,釋放內存
        q = p;
        p = p->next;
        free(q);
    }
    L = NULL; // L置為NULL
}

遍歷打印單鏈表

/**
 * 遍歷打印單鏈表的所有元素
 */
void PrintList(LinkList head) {
    LinkList p = head->next;

    if (p == NULL) {
        cout << "List is NULL!" <<endl;
    } else {
        while (p != NULL) {
            printf("%d ", p->data);
            p = p->next;
        }
        printf("\n");
    }
}

附上完整代碼

#include<cstdlib>
using namespace std;
#define LEN sizeof(Node)
typedef int DataType;
typedef struct Node {
    DataType data;
    struct Node *next;
} Node, *LinkList;

/**
 * 頭插法創建單鏈表
 * @param head
 */
void CreateListHead(LinkList &head) {
    DataType x;
    LinkList p;

    head = (LinkList)malloc(LEN);
    head->next = NULL;
    scanf("%d", &x);
    while (x != -1) {
        p = (LinkList)malloc(LEN);
        p->data = x;
        p->next = head->next;
        head->next = p;
        scanf("%d", &x);
    }
}

/**
 * 尾插法創建單鏈表
 * @param head
 */
void CreateListTail(LinkList &head) {
    LinkList p, q;
    DataType x;

    head = (LinkList)malloc(LEN);
    q = head;
  	scanf("%d", &x);
    while (x != -1) {
        p = (LinkList)malloc(LEN);
        p->data = x;
        q->next = p;
        q = p;
        scanf("%d", &x);
    }
    q->next = NULL;
}

/**
 * 獲取指定位置的元素
 * @param head 單鏈表頭指針
 * @param i 位置
 * @param e 獲取的元素賦值該參數
 * @return 0:獲取失敗;1:獲取成功
 */
int GetElement(LinkList head, int i, DataType &e) {
    LinkList p = head->next;
    int j = 1;

    while (p && j < i) {
        p = p->next;
        j++;
    }
    if (!p || j > i) {
        return 0;
    }
    e = p->data;
    return 1;
}

/**
 * 獲取某個元素的位置
 * @param head
 * @param e
 * @return 元素的位置
 */
int LocateElement(LinkList head, int e) {
    LinkList p = head->next;
    int j = 1;

    while (p && p->data != e) {
        p = p->next;
        j++;
    }
    if (!p) {
        return 0;
    }
    return j;
}

/**
 * 在單鏈表插入元素到位置i
 * @param head 單鏈表的頭指針
 * @param i 插入位置
 * @param e 插入元素
 * @return 1:插入成功,0:插入失敗
 */
int InsertList(LinkList head, int i, DataType e) {
    LinkList p = head;
    int j = 1;

    while (p && j < i) {
        p = p->next;
        j++;
    }
    if (!p || j > i) {
        return 0;
    }
    LinkList q = (LinkList)malloc(LEN);
    q->data = e;
    q->next = p->next;
    p->next = q;
}

/**
 * 刪除指定位置的元素
 * @param head
 * @param i 位置
 * @param e 被刪除的元素的值存放在e中
 * @return 1:刪除成功,0:刪除失敗
 */
int DeleteList(LinkList head, int i, DataType &e) {
    LinkList p = head;
    int j = 1;

    while (p && j < i) {
        p = p->next;
        j++;
    }
    if (!p || j > i) {
        return 0;
    }
    LinkList s = p->next;
    e = s->data;
    p->next = s->next;
    free(s);
    return 1;
}

/**
 * 獲取單鏈表的長度
 * @param head
 * @return
 */
int LengthLinkList(LinkList head) {
    LinkList p = head->next;
    int count = 0;

    while (p) {
        count++;
        p = p->next;
    }
    return count;
}

/**
 * 合並兩個非遞減的單鏈表,新的鏈表仍然非遞減
 * @param La
 * @param Lb
 * @param Lc
 */
void MergeList(LinkList La, LinkList Lb, LinkList &Lc) {
    LinkList pa, pb, pc;

    pa = La->next;
    pb = Lb->next;
    pc = Lc = (LinkList)malloc(LEN);

    while (pa && pb) {
        if (pa->data <= pb->data) {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        } else {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa ? pa : pb;
    free(Lb);
}

/**
 * 銷毀鏈表
 * @param L
 */
void Destroy(LinkList &L) {
    LinkList p, q;
    p = L;
    while (p) {
        q = p;
        p = p->next;
        free(q);
    }
    L = NULL;
}

/**
 * 遍歷打印單鏈表的所有元素
 * @param head
 */
void PrintList(LinkList head) {
    LinkList p = head->next;

    if (p == NULL) {
        cout << "List is NULL!" <<endl;
    } else {
        while (p != NULL) {
            printf("%d ", p->data);
            p = p->next;
        }
        printf("\n");
    }
}
int main() {
    LinkList L;
    printf("頭插法創建單鏈表:(輸入以-1結束)\n");
    CreateListHead(L);
    PrintList(L);
    printf("尾插法創建單鏈表:(輸入以-1結束)\n");
    CreateListTail(L);
    PrintList(L);
    InsertList(L, 1, 100);
    printf("在1號位置插入100後,單鏈表如下:\n");
    PrintList(L);
    DataType e;
    DeleteList(L, 1, e); 
    printf("刪除1號位置的元素,被刪除的元素為:\n");
    printf("刪除後的單鏈表為:\n"); 
    PrintList(L);
    printf("單鏈表的長度為:%d\n", LengthLinkList(L));
    GetElement(L, 1, e);
    printf("1號位置的元素為:%d\n");
    printf("元素4在單鏈表中的位置為:%d\n", LocateElement(L, 4));
	cout << endl;
    LinkList La, Lb, Lc;
    printf("尾插法創建單鏈表La:\n");
    CreateListTail(La);
    PrintList(La);
    printf("尾插法創建單鏈表Lb:\n");
    CreateListTail(Lb);
    PrintList(Lb);
    MergeList(La, Lb, Lc);
    printf("合並單鏈表La和Lb後的新單鏈表Lc如下:\n");
    PrintList(Lc);
    return 0;
}

運行結果: 

 註意:

寫法采用瞭C++引用參數的寫法,LinkList &head,C語言下不支持這種寫法,需要在C++環境下使用,即.cpp文件。

下面附上C語言的:

 /**
 * LinkList 本身已經是結構體指針,參數再使用LinkList *的形式
 * 可以理解為要想改變一個結構體指針,則需要取指針的指針。
 * 類似於改變int a,則需要使用 int *a,這裡要改變LinkList head,則需要使用LinkList *head
 */
void CreatListTail(LinkList *head) {
    int x;
    LinkList *p, *q;

    *head = (LinkList *) malloc(LEN);
    q = *head;

    scanf("%d", &x);
    while (x != -1) {
        p = (LinkList *) malloc(LEN);
        p->data = x;
        q->next = p;
        q = p;
        scanf("%d", &x);
    }
    q->next = NULL;
}
// 可以不傳參,函數裡面定義頭指針,創建鏈表,然後把頭指針返回,主函數用結構體指針接收即可
LinkList CreateListhead() {
    int x;
    LinkList *head, *p;

    head = (LinkList *) malloc(LEN);
    head->next = NULL;

    scanf("%d", &x);
    while (x != -1) {
        p = (LinkList *) malloc(LEN);
        p->data = x;
        p->next = head->next;
        head->next = p;
    }
    return head;
}

到此這篇關於C語言實現單鏈表基本操作方法的文章就介紹到這瞭,更多相關C語言單鏈表內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: