數(shù)據(jù)結(jié)構(gòu) 線性表 單鏈表 c語言實(shí)現(xiàn)可運(yùn)行

線性表


線性表概念

線性表定義:具有相同特性數(shù)據(jù)元素的有限序列。
線性表的邏輯結(jié)構(gòu):線性結(jié)構(gòu)。只有一個(gè)表頭,只有一個(gè)表尾。表頭元素沒有前驅(qū),表尾元素沒有后繼。其余都有一個(gè)直接前驅(qū)與后繼。
線性表的物理結(jié)構(gòu):順序存儲(chǔ)結(jié)構(gòu)和鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)

  • 順序表:將元素按照其邏輯順序,依次存儲(chǔ)在指定位置開始的一片連續(xù)的存儲(chǔ)空間中。
  • 鏈表:在內(nèi)存中可以不連續(xù)。每個(gè)結(jié)點(diǎn)中不止包括所存元素的信息,還有元素之間邏輯關(guān)系的信息。如單鏈表中后繼結(jié)點(diǎn)。

兩種儲(chǔ)存結(jié)構(gòu)的比較:

順序表:

  1. 隨機(jī)訪問性 (知道0點(diǎn)位置。就可以在o(1)時(shí)間找到想要的元素)
  2. 占用連續(xù)的存儲(chǔ)空間
  3. 靜態(tài)分配:一旦分配好,操作過程中不會(huì)發(fā)生改變
  4. 做操作需要移動(dòng)多個(gè)元素

鏈表:
1.不支持隨機(jī)訪問(必須遍歷)
2.結(jié)存的存儲(chǔ)空間利用率較順序表較低(多了結(jié)點(diǎn)邏輯信息)
3.動(dòng)態(tài)分配
4.做操作無須移動(dòng)元素


鏈表的五種形式

1.單鏈表

此處輸入圖片的描述
此處輸入圖片的描述

帶頭結(jié)點(diǎn) :head->始終不為空,head->next為NULL時(shí)為空鏈表
不帶頭結(jié)點(diǎn):head為NUll時(shí)是空鏈表

帶頭結(jié)點(diǎn)的單鏈表的優(yōu)點(diǎn):
在鏈表第一個(gè)位置上進(jìn)行的操作(插入、刪除)和其它位置上的操作一致,無須進(jìn)行特殊處理;
無論鏈表是否為空,head一定不為空,這使得空表和非空表的處理一致。

2.雙鏈表

此處輸入圖片的描述
此處輸入圖片的描述

比單鏈表在結(jié)點(diǎn)上多了個(gè)前驅(qū)結(jié)點(diǎn)。使得可以從后向前訪問。

3.循環(huán)單鏈表

此處輸入圖片的描述
此處輸入圖片的描述

最后一個(gè)指針域指向開始結(jié)點(diǎn)。
可以做到從任何一個(gè)結(jié)點(diǎn)出發(fā),訪問任何一個(gè)結(jié)點(diǎn)。
空鏈表:head = head->next

4.循環(huán)雙鏈表

此處輸入圖片的描述
此處輸入圖片的描述

空鏈表:head = head->next或head = head->prior
5.靜態(tài)鏈表
此處輸入圖片的描述
此處輸入圖片的描述


順序表

順序表基本操作:

初始化
插入
刪除
查找
打印
求指定位置元素

代碼:

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int data[100];
    int length;
}sqList;//順序表的結(jié)構(gòu)體定義

/**順序表操作**/
//查找
int findElem(sqList L,int x)//查找
{
    for(int i = 0;i<L.length;++i)
    {
        if(x == L.data[i])
            return i;
    }
    return -1;
}

//插入
int insertElem(sqList *L,int p,int x)
{
    int i;
    if(p<0||p>L->length||L->length == 100)//順序表超過最大允許值
        return 0;
        
    for(i = L->length -1;i>=p;--i)
        L->data[i+1]=L->data[i];
    L->data[p] = x;
    ++(L->length);
    return 1;
}
//刪除
int deleteElem(sqList *L,int p ,int *x)//將被刪除的元素賦值給x,可以不要這個(gè)步驟
{
    int i;
    if(p<0||p>L->length-1)
        return 0;
    *x = L->data[p];
    for(i = p;i<L->length-1;++i)
       L->data[i]=L->data[i+1];
    --(L->length);
    return 1;
}
//初始化
void initList(sqList *L)
{
    L->length = 0;
}

//求指定位置元素
int getElem(sqList L,int p,int *x)
{
    if(p<0||p>L.length-1)
        return 0;
    *x =L.data[p];
    return 1;
}
//打印
void printList(sqList L)
{
    for(int i =0;i<L.length;++i)
        printf("%d ",L.data[i]);
}
int main()
{
    sqList A;
    int x=0;
    initList(&A);
    insertElem(&A,0,1);
    insertElem(&A,1,2);
    insertElem(&A,1,3);
    printf("before delete:\n",x);
    printList(A);
    deleteElem(&A,1,&x);
    printf("\n after delete:\n",x);
    printList(A);
    printf("刪除的值是%d\n",x);
    getElem(A,1,&x);
    printf("取的值是%d\n",x);
    printf("元素位置是%d\n",findElem(A,1));
    return 0;

}
/**
輸出如下
before delete:
1 3 2
 after delete:
1 2 刪除的值是3
取的值是2
元素位置是0
**/

單鏈表

單鏈表基本操作:

創(chuàng)建鏈表
插入鏈表(頭、尾插法)
刪除鏈表
打印鏈表
查找鏈表

代碼實(shí)現(xiàn):

//------------單鏈表-------------------
//單鏈表結(jié)點(diǎn)定義
typedef struct lNode
{
    int data;
    struct lNode *next;//在此語句時(shí)lNode別名還未生效,所以需要用struct lNode來聲明結(jié)構(gòu)體變量
}lNode;

//創(chuàng)建表頭
void createListR(lNode **c)
{
    (*c) =(lNode*)malloc(sizeof(lNode));
    (*c)->next=NULL;

}

//尾插入
lNode *r = NULL;//全局變量尾指針
void insertLnodeR(lNode **c,int data)
{
    lNode *s;
    if(r==NULL)
        r = (*c);

    s = (lNode*)malloc(sizeof(lNode));
    s->data = data;

    r->next=s;
    r=r->next;
    r->next=NULL;

}
//打印鏈表
void printListLnode(lNode *headNode)
{
    lNode* pMove = headNode->next;
    printf("數(shù)據(jù)如下:\n");
    
    while(pMove)
    {
        printf("%d\n",pMove->data);
        pMove = pMove->next;
    }
}
//刪除鏈表
void deleteLNode(lNode **c,int x)
{
    lNode *p,*pf;
    p = (*c)->next;
    pf =(*c);//指向頭指針
    
    if(p == NULL)
        printf("無法刪除鏈表為空");
    while(p->data != x)//如果不為x,使指向前驅(qū)結(jié)點(diǎn)的pf和該節(jié)點(diǎn)p指針向后移動(dòng)
    {
        pf = p;
        p = p->next;
        
        if(p == NULL)
            {
                printf("沒有找到相關(guān)信息\n");
                return;
            }
        }
        
    pf->next = p->next;//將p結(jié)點(diǎn)從鏈表中移除
    free(p);//釋放p結(jié)點(diǎn)空間
    
    int main()
{
    lNode *c;
    createListR(&c);//以地址的地址為參數(shù),需要取指針的地址(&c),而不是指針(c)
    insertLnodeR(&c,2);
    insertLnodeR(&c,3);
    printListLnode(c);
    deleteLNode(&c,3);
    printListLnode(c);
    return 0;

}
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容