單鏈表的初始化,整表創建,單個元素插入,單個元素刪除,整表刪除等操作


      很早之前學的數據結構,放了很久后,以致對里面的一些操作都有些遺忘,故而再次溫習了一下數據結構,並整理了一點兒筆記,放在這里和大家分享, 我的代碼注釋的已經很詳細了,對於容易出錯的地方我也都有標注,歡迎大家交流。

#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#define OK 1
#define ERROR 0

//#define 
typedef int Status;//函數返回的狀態值類型
typedef int ElemType;
typedef struct Node
{
    ElemType data;
    struct Node *next;
} Node;//定義一個單鏈表存儲結構

typedef struct Node *LinkList;//定義一個線性表,定義的是Node結構體的指針

//創建一個具有n個元素的單鏈線性表,采用頭插法創建,注意:其中已經包含了初始化操作
//初始化鏈表,函數調用完畢后,L會指向一個空的鏈表,即會改變指針的值,所以要用*L
//*L表示結構體指針的指針
Status List_Link_Create(LinkList *L,int n)//頭插法
{
    LinkList p;
    *L =(LinkList) malloc(sizeof(Node));//產生一個頭結點,並使得*L指向這個頭結點,於是*L便是一個頭指針,頭指針是鏈表的必要元素
    if (L == NULL)
        return ERROR;
    (*L)->next = NULL;//使得頭指針指向的內容為空,建立一個帶頭結點的單鏈表
    printf("請輸出n個隨機生成的數字:");
    for (int i = 0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));//生成新節點
        p->data = rand() % 100 + 1;//隨機生成100以內的數字
        printf("%d", p->data);
        printf(" ");//字符與字符之間空格
        
        p->next = (*L)->next;
        (*L)->next = p;//插入到表頭
    }
    printf("\n");//換行
    return OK;
}

Status List_Link_Length(LinkList L)//求出單鏈表的長度
{
    int j = 0;
    LinkList p;
    p = L;
    while (p != NULL)
    {
        p = p->next;
        j++;
    }
    printf("單鏈表當前的長度=%d",j);
    return j;
}
//Status List_Link_Ini(LinkList L)//初始化一個線性單鏈表
//{
//    L = (LinkList)malloc(sizeof(Node));//產生一個頭結點,並使得L指向這個頭結點,於是L便是一個頭指針,頭指針是鏈表的必要元素
//    if (L == NULL)
//        return ERROR;
//    L->next = NULL;//使得頭結點的指針域為空
//    return OK;
//}

//銷毀鏈表L,釋放鏈表L申請的內存,使L的值重新變為NULL,所以會改變L的值,得用*L
Status List_Link_Destory(LinkList *L)
{
    LinkList p,q;
    p = (*L)->next;
    while (p)
    {
        q = p->next;
        free(p);
        p = q;
    }
    (*L)->next = NULL;//頭節點的指針域為空
    return OK;
}

Status List_Link_Insert(LinkList *L, int i, ElemType e)//在L中第i個元素之前插入新的數據元素e
{
    int j;
    LinkList p, s;
    p = *L;
    j = 1;
    while (p&&j<i)//遍歷尋找第i個節點
    {
        p = p->next;
        ++j;
    }
    if (!p || j > i)
        return ERROR;//第i個元素不存在
    s = (LinkList)malloc(sizeof(Node));//生成一個新節點
    s->data = e;
    s->next = p->next;//將p的后繼節點賦值給s的后繼
    p->next = s;
    printf("插入節點的元素的值為:%d\n", e);
    return OK;//插入成功

}

//刪除L的第i個數據元素,並用e返回其值
//注意這里是*e,而不是e,區別於插入當中的變量e
Status List_Link_Delete(LinkList *L, int i, ElemType *e)
{
    int j=1;
    LinkList p, q;
    p = *L;
    while (p->next&&j<i)//遍歷尋找第i個元素
    {
        p = p->next;
        ++j;
    }
    if (!(p->next) || j > i)
        return ERROR;//第i個元素不存在

    q = p->next;//q表示即將被刪除元素的節點
    *e = q->data;
    p->next = q->next;//將q    后繼賦值給p的后繼
    free(q);//q被利用完畢后,將q釋放
    printf("刪除第%d個節點的元素值為:%d\n", i, *e);
    return OK;

}

Status List_Link_GetElem(LinkList L, int i, ElemType *e)//取出單鏈表L中的第i個元素,並通過*e返回
{
    int j;
    LinkList p;
    p = L->next;//找到單鏈表L中第一個節點
    j = 1;
    while (p&&j < i)
    {
        p = p->next;
        ++j;
    }
    if (!p || j > i)
        return ERROR;//第i個元素不存在
    
    *e = p->data;//取出第i個元素的數據域並傳值給*e
    printf("被取出的元素的值為:");
    printf("%d\n", *e);
    return OK;
}
int main()//測試函數
{
    LinkList L1;
    ElemType f,h;
    List_Link_Create(&L1, 6);
    List_Link_GetElem(L1, 3, &f);
    List_Link_Insert(&L1, 3, 15);//在鏈表的第3個節點之前插入元素15
    List_Link_Delete(&L1, 3, &h);//刪除鏈表的第3個節點的元素,並返回給h輸出
    return OK;
}









/*1.對於LinkList L : L是指向定義的node結構體的指針, 可以用->運算符來訪問結構體成員, 即L->elem, 而(*L)就是個Node型的結構體了,
可以用點運算符訪問該結構體成員, 即(*L).elem;

2.對於LinkList *L:L是指向定義的Node結構體指針的指針, 所以(*L)是指向Node結構體的指針, 
可以用->運算符來訪問結構體成員, 即(*L)->elem, 當然, (**L)就是Node型結構體了, 所以可以用點運算符來訪問結構體成員, 即(**L).elem;

3.在鏈表操作中, 我們常常要用鏈表變量作物函數的參數, 這時, 用LinkList L還是LinkList *L就很值得考慮深究了, 
一個用不好, 函數就會出現邏輯錯誤, 其准則是:如果函數會改變指針L的值, 而你希望函數結束調用后保存L的值, 那你就要用LinkList *L, 
這樣, 向函數傳遞的就是指針的地址, 結束調用后, 自然就可以去改變指針的值;而如果函數只會修改指針所指向的內容,
而不會更改指針的值, 那么用LinkList L就行了;*/


下面是我在vs2013中的測試結果:

請輸出n個隨機生成的數字:42 68 35 1 70 25
被取出的元素的值為:1
插入節點的元素的值為:15
刪除第3個節點的元素值為:15
請按任意鍵繼續. . .


免責聲明!

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



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