資料結構 線性表之帶頭結點單鏈表

2021-09-11 02:34:30 字數 4090 閱讀 2051

之前跟著朱老師寫的乙個帶頭結點的:

建立鍊錶時有兩種方法,

一種是先初始化(建立乙個空鍊錶),然後對這個空鍊錶進行結點輸入,建立鍊錶;這個時候,由於已經有了頭結點,將其傳入,直接在頭結點的後面進行操作;

另外一種是將初始化和建立鍊錶放到乙個函式裡,這時候傳入的鍊錶就什麼都沒有,連頭結點也沒有;先建立頭結點,讓傳入的指標指向頭結點,接著繼續輸入資料;  也有的書上是什麼都不傳入,最後生成乙個鍊錶後傳出這個鍊錶。

插入找前驅(第k個位置的前驅)

刪除找前驅

//這個要從頭結點開始

//如果在第1個位置插入,前驅就是頭結點  

for(pre = (*l); pre && i < k-1; i++)

if(!pre) 

//這個要從頭結點開始

//如果要刪除第1個位置的結點,前驅就是頭結點

for(pre = (*l); pre->next && i < k-1; i++)

if(pre->next == 0) 

這幾天寫的這些個程式還有乙個小缺陷,就是那個要修改鍊錶資料的形參中,並不需要使用**l,用*l就可以;因為即使這個是傳值,但是傳的是指標的值,指標指向的內容是不變的。

#include#includetypedef unsigned char  boolean;

#define true 1

#define false 0

typedef int elemtype;

typedef struct lnodelnode;

/*//有些書上描述鍊錶這樣子描述,就是多定義了乙個指向結點的指標而已

typedef struct lnodelnode, *linklist;

*/void initlinklist(lnode **l); //初始化的意思是構造乙個空鍊錶

void createlinklist(lnode **l); //尾插法 由於之前已經初始化建立了空鍊錶,所以這個函式傳入的鍊錶就直接加有效資料結點就可以了

void createlinklist2(lnode **l); //頭插法 尾插法需要乙個指標,始終指向末結點 頭插法則不用

//輸出鍊錶

void printlinklistdata(lnode *l);

//查詢

elemtype getelem(lnode *l, int k); //找出帶頭結點單鏈表中第i個位置的結點的資料

lnode *getelem2(lnode *l, int k); //找出帶頭結點單鏈表中第i個位置的結點的指標

lnode *locateelem(lnode *l, elemtype x); //找到帶頭結點單鏈表中值為x結點的指標

//插入

void insertelem(lnode **l, int k, elemtype x); 在帶頭結點單鏈表中第i個位置上插入新結點

//這就意味著是前插,但是所有的前插都是找到該結點的前驅結點,然後再進行後插

//刪除

void deleteelem(lnode **l, int k);

boolean isempty(lnode *l);

int lengthoflinklist(lnode *l); //鍊錶長度

int lengthoflinklist(lnode *l)

return i;

} boolean isempty(lnode *l)

void deleteelem(lnode **l, int k)

for(pre = (*l); pre && i < k-1; i++)

if(!pre)

p = pre->next; //p指向要刪除的結點

pre->next = p->next;

free(p);

printf("刪除完畢!\n");

*/ //找前驅結點

if(k < 1)

for(pre = (*l); pre->next && i < k-1; i++)

if(pre->next == 0)

p = pre->next; //p指向要刪除的結點

pre->next = p->next;

free(p);

printf("刪除完畢!\n");

} //這就意味著是前插,但是所有的前插都是找到該結點的前驅結點,然後再進行後插

void insertelem(lnode **l, int k, elemtype x)else if(k == 1)else if(k = 1)else

//printf("pre->data=%d\n", pre->data);

*/ //找前驅結點

if(k < 1)

for(pre = (*l); pre && i < k-1; i++)

if(!pre)

//為新結點開闢空間

p = (lnode *)malloc(sizeof(lnode));

p->data = x;

p->next = pre->next;

pre->next = p;

printf("插入完畢!\n");

} //從單鏈表第乙個結點開始,由前往後依次比較表中各結點資料域的值,若某結點資料域的值等於x,則返回該結點的指標;

//若整個單鏈表中沒有這樣的結點,則返回null

lnode *locateelem(lnode *l, elemtype x)

return p; //返回值為x的結點的指標,如果沒有這樣的值,p=null,直接返回p即可

} //在單鏈表中從第乙個結點出發,順指標next域逐個往下搜尋,直到找到第k個結點為止,否則返回最後乙個結點指標域null

lnode *getelem2(lnode *l, int k)

while(p && i < k)

return p; //返回第k個結點的指標,如果k大於表長,p=null,直接返回p即可 }

elemtype getelem(lnode *l, int k)

while(p && i < k)

if(!p)

return p->data; }

void printlinklistdata(lnode *l)

printf("\n");

} void createlinklist2(lnode **l) }

//下面的這個建立鍊錶的方法,是把初始化和建立鍊錶放到了一起,即傳入的鍊錶什麼都沒有,連頭指標都沒有

void createlinklist(lnode **l) }

/*void createlinklist(lnode **l)

}void initlinklist(lnode **l)else}*/

void main(void); //這樣子的話,直接定義了乙個結點,並且賦初值為0,就相當於定於了乙個空鍊錶

lnode *list = null; //這樣子的話,只是定義了乙個指標,並沒有具體的開闢結點空間,所以需要初始化,構造乙個空鍊錶

createlinklist(&list);

printlinklistdata(list);

//printf("第%d個地方的值為:%d\n", 2, getelem(list, 2));

//printf("第%d個地方的值為:%d\n", 2, (getelem2(list, 2))->data);

//printf("值為%d的結點的指標所指向的值為:%d\n", getelem(list, 2), (locateelem(list, getelem(list, 2)))->data);

//insertelem(&list, 6, 6);

//printlinklistdata(list);

deleteelem(&list, 5);

printlinklistdata(list);

printf("鍊錶是否為空:%d\n", isempty(list));

printf("鍊錶長度為:%d\n", lengthoflinklist(list));

}

c資料結構線性表之單鏈表 帶頭結點 基本操作

include include define maxsize 10 define elemtype char define ok 1 define error 0 typedef struct node 結點型別定義 node,linklist linklist為結構體指標型別 換行函式 void ...

資料結構 線性表之單鏈表

線性表 亦作順序表 是最基本 最簡單 也是最常用的一種資料結構。線性表中資料元素之間的關係是一對一的關係,即除了第乙個和最後乙個資料元素之外,其它資料元素都是首尾相接的。線性表有兩種儲存結構 順序儲存結構,即儲存單元在一段連續的位址上儲存,常見的陣列就是順序儲存結構的線性表 鏈式儲存結構,即儲存單元...

資料結構 帶頭結點的單鏈表

比較坑爹的基礎啊,大把時間浪費在建構函式上,建構函式 出生決定命運!自己解決的bug,感覺還不錯。其實程式的核心是演算法,演算法建立在資料結構的基礎之上。大部分的程式設計師現在學的基本都是規則,而不是創造。但掌握了規則,也能創造很多財富。重新鞏固我弱爆了的資料結構,沒敲完資料結構的程式設計師不是好領...