單鏈表:創建、判空表、計算長度、銷毀鏈表、清空鏈表、取第i個位置的值、單鏈表的查找(返回地址、位序)、在第i個元素前插入值為e的結點、刪除單鏈表、頭插法建立單鏈表、遍歷單鏈表、尾插法建立單鏈表


 

 

 

當鏈表的每個結點只包含一個指針域時,我們稱此鏈表為單鏈表。

關於單鏈表的存取,有時候我們在單鏈表的第一個結點(有效元素)之前附設一個結點,稱之為頭結點;指向頭結點的指針,稱之為頭指針;對單鏈表的存取必須從頭指針開始進行,由於單鏈表的最后一個數據元素沒有直接后繼,則指針為NULL。

 

 

 

 

 

 

對於頭結點,數據域可以不存儲任何信息,也可存儲如鏈表長度等附加信息。

下面是帶頭結點的單鏈表與空表的比較圖。

 

 

頭指針與頭結點不同,頭結點即第一個結點,頭指針是指向第一個結點的指針。鏈表中可以沒有頭結點,但不能沒有頭指針。

關於頭指針:

  • 在線性表的鏈式存儲結構中,頭指針是指鏈表指向第一個結點的指針,若鏈表有頭結點,則頭指針就是指向鏈表頭結點的指針。
  • 頭指針具有標識作用,故常用頭指針冠以鏈表的名字。
  • 無論鏈表是否為空,頭指針均不為空。頭指針是鏈表的必要元素。

關於頭結點:

  • 頭結點是為了操作的統一與方便而設立的,放在第一個元素結點之前,其數據域一般無意義(當然有些情況下也可存放鏈表的長度、用做監視哨等等)。
  • 有了頭結點后,對在第一個元素結點前插入結點和刪除第一個結點,其操作與對其它結點的操作統一了。
  • 首元結點也就是第一個元素的結點,它是頭結點后邊的第一個結點。
  • 頭結點不是鏈表所必需的。

 

 

 

 

 

頭插法建立單鏈表:

 

 

 尾插法建立單鏈表:

 

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "iostream"
using namespace std;


#define ListSize 10

//單鏈表的創建
typedef struct LNode {
    int data;//數據域
    struct LNode *next;//鏈接域
}LNode,*Linklist;

//單鏈表的初始化
bool InitList(Linklist &L)
{
    L = new LNode;//創建一個新的結點作為頭結點,用頭指針L指向頭結點
    L->next = NULL;//讓頭結點的指針域為空

    return true;
}

//判斷單鏈表是否為空表:指針域那邊為空
bool ListEmpty(Linklist L)
{
    if (L->next)
        return false;
    else
        return true;
}

//銷毀單鏈表---不保留頭結點
bool DestroyList(Linklist &L)
{
    LNode *p;
    while (L)
    {
        p = L;
        L = L->next;
        delete p;
    }
    return true;
}

//清空單鏈表---保留頭指針和頭結點,頭結點的指針域要置為空
bool DeleteList(Linklist &L)
{
    LNode *p, *q;
    p = L->next;
    while (p)
    {
        q = p->next;
        delete p;
        p = q;
    }
    L->next = NULL;
    return true;
}

//求單鏈表的表長
int ListLength(Linklist L)
{
    int i = 0;
    LNode *p;
    p = L->next;
    while (p)
    {
        p = p->next;
        i++;
    }
    return i;
}

//取第i個元素的值
bool GetElem(Linklist L, int i, int &e)
{
    LNode *p;
    p = L->next;
    int j = 1;
    while (p && j<i)
    {
        p = p->next;
        j++;
    }
    //查找到最后的情況以及i可能為負數的情況
    if (!p || j > i)
        return false;
    e = p->data;
    return true;
}

//單鏈表的查找---查找某個元素值,返回該元素的地址
LNode *LocateElem(Linklist L, int e)
{
    LNode *p;
    p = L->next;
    while (p && p->data != e)
    {
        p = p->next;
    }
    return p;
}

//單鏈表的查找---查找某個元素值,返回該元素的序號
int LocateElemInt(Linklist L, int e)
{
    LNode *p;
    p = L->next;
    int i = 1;
    while (p && p->data != e)
    {
        p = p->next;
        i = i + 1;
    }
    if (p)
        return i;
    else
        return 0;
}

//單鏈表的插入---在第i個結點前插入值為e的結點(需要找第i-1個結點)
bool ListInsert(Linklist &L, int i, int e)
{
    LNode *p, *s;
    p = L;
    int j = 0;
    while (p && j < i - 1)
    {
        p = p->next;
    }
    if (!p || j > i-1)
        return false;
    s = new LNode;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

//單鏈表的刪除---刪除第i個結點,需要找到第i-1個結點
bool DeleteList(Linklist &L, int i, int &e)
{
    LNode *p, *q;
    int j = 0;
    p = L;
    while (p && j < i - 1)
    {
        p = p->next;
    }
    if (!(p->next) || j > (i-1))
        return false;
    q = p->next;
    e = q->data;
    p->next = p->next->next;
    delete q;
    return true;
}

//頭插法建立單鏈表
void CreatList_H(Linklist &L, int n)
{
    L = new LNode;
    L->next = NULL;
    for (int i = n; i > 0; i--)
    {
        LNode *p = new LNode;//建立新結點
        cin >> p->data;//讀入數據
        p->next = L->next;
        L->next = p;
    }
    cout << "創建長度為" << n << "的單鏈表完畢!"<<endl;
}

//尾插法建立單鏈表
void CreatList_R(Linklist &L, int n)
{
    L = new LNode;
    L->next = NULL;
    LNode *r = L;
    for (int i = 0; i < n; i++)
    {
        LNode *p = new LNode;
        cin >> p->data;
        p->next = NULL;
        r->next = p;
        r = p;
    }
}


//單鏈表內容的遍歷
void ListDisply(Linklist L)
{
    printf("單鏈表中的內容為:");
    LNode *p;
    p = L->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n\n\n\n");
}



int main()
{
    //創建一個鏈表
    Linklist L;
    InitList(L);

    Linklist K;
    InitList(K);

    Linklist P;
    InitList(P);

    //創建三個結點
    LNode *a, *b, *c;
    a = new LNode;
    b = new LNode;
    c = new LNode;

    //判斷空表
    if (!ListEmpty(L))
        printf("it is not empty!\n");
    else
        printf("it is empty!\n");

    //將三個結點串成串連成線兒
    L->next = a;
    a->next = b;
    b->next = c;
    c->next = NULL;


    if (!ListEmpty(L))
        printf("it is not empty!\n");
    else
        printf("it is empty!\n");

    //給三個結點的數據域賦值
    a->data = 23;
    b->data = 87;
    c->data = 99;

    printf("the length of list is: %d\n", ListLength(L));

    //獲取第i個元素的值
    int e;
    GetElem(L, 2, e);
    printf("the value of second is:%d\n", e);

    //單鏈表的查找---返回地址
    printf("\n\nLocateElem--23:  %x\n", (unsigned)LocateElem(L, 23));
    printf("LocateElem--87:  %x\n", (unsigned)LocateElem(L, 87));
    printf("LocateElem--99:  %x\n", (unsigned)LocateElem(L, 99));
    //單鏈表的查找---返回序號
    printf("LocateElemInt--87:  %d\n\n\n", LocateElemInt(L, 23));

    //頭插法建立單鏈表---輸入幾個元素
    cout << "頭插法建立單鏈表,請輸入數據:" << endl;
    CreatList_H(K, 5);
    printf("the length of list is: %d\n", ListLength(K));
    //單鏈表的遍歷
    ListDisply(K);

    //尾插法建立單鏈表---輸入幾個元素
    cout << "尾插法建立單鏈表,請輸入數據:" << endl;
    CreatList_R(P,5);
    printf("the length of list is: %d\n\n", ListLength(P));
    //單鏈表的遍歷
    ListDisply(P);


    getchar();
    getchar();
    getchar();
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM