帶頭結點的單鏈表

2021-09-29 23:50:32 字數 2921 閱讀 2318

**帶頭結點的單鏈表

1、頭結點:在棧區開闢,指標域指向第乙個首元結點,資料域不儲存資料,可以儲存當前結點的個數;

2、普通結點:無論是頭結點還是普通結點都是乙個結構體型別,由指標域和資料域組成;

指標域指向下乙個結點,儲存下乙個結點的位址;

資料域可以設定成聯合體型別,成員由資料元素和結點個數組成,之所以將資料域設定成聯合體型別,是因為考慮到頭結點資料域儲存結點個數,普通結點資料域儲存結點個數。

3、帶頭結點的單鏈表的基本操作

#define true 1;

#define false 0;

typedef int elemtype;

typedef union data//資料域:聯合體型別,成員:資料元素,結點個數;

data;

typedef struct node//結點

lnode, * linklist;

new_node->data.val = val;

new_node->next = next;

return new_node;

}static linklist find_pos_p(linklist head,int pos)//找pos的前乙個結點

return p;

}int init_headlinklist(linklist head)//初始化, next,data

head->next = null;

head->data.num = 0;

return true;

}int insert_headlinklist_pos(linklist head,elemtype val,int pos)//按位置插入 o(n)

if (pos<0||pos>head->data.num)

//找pos之前的結點

/*linklist p = head;

while(pos > 0)

*///寫乙個函式來代替找pos之前的結點

linklist p = find_pos_p(head,pos);

p->next = new_node;

head->data.num++;

return true;

}int delete_headlinklist_pos(linklist head,int pos)//按位置刪除 o(n)

if (pos<0||pos>=head->data.num)

linklist p = find_pos_p(head,pos);

linklist q = p->next;

p->next = q->next;

free(q);

q = null;

head->data.num--;

return true;

}linklist findnode_pos(linklist head,int pos)//按位置查詢 o(n)

if (pos<0||pos>=head->data.num)

linklist p = find_pos_p(head,pos);

return p->next;

}int clear_headlinklist(linklist head)//清空

while(head->data.num > 0) }

return true;

}int destroy_headlinklist(linklist head)//銷毀

4、帶頭結點的單鏈表的經典面試題

只講思路和方法,**自己實現

第一題:找倒數第k個結點(不知道結點的個數)

1.1、知道結點個數:假設已知結點個數為n,倒數第k個結點,就是正數的第n-k個結點;

1.2、不知道結點個數:設定兩個結點指標p和q,當q走到結尾的時候,p剛好走到倒數第k個結點處;

p即為所求的結點,p和q相差的結點數就為k;

注意:k要判斷合法性;

第二題:在時間複雜度為o(1)的情況下刪除結點p(p不是尾結點)

2.1、刪除結點p要找p的前乙個結點,如果按照這種方法,時間複雜度為o(n),不符合要求;

2.2、刪除乙個結點其實是刪除這個結點的資料,那麼可以找結點p的直接後繼q,將p的直接後繼q中的資料複製給p

那麼將q->next賦給p->next,在將q給刪了,從而間接刪除了p;

這就是為什麼結點p不能是尾結點,因為尾結點的直接後繼為null;

第三題:單鏈表的原地逆置

3.1、設定3個指標變數求解,s=null,p=head->next,q=p->next;

3.2、只設定兩個指標變數,p=head->next,q=p->next,head->next=null,單鏈表的原地逆置就相當於頭插;

第四題:判斷兩個單鏈表是否相交,找到相交的乙個結點

解:y型結構:兩個單鏈表相交;

設定兩個指標變數p和q(p和q分別代表兩條單鏈表);

p和q同時遍歷一遍的長度之差就是他們相交之前的長度之差。

因此可以讓長度較長的單鏈表先走乙個差值,然後在同時遍歷,p和q相等的地方就是相交點。

第五題:判斷單鏈表是否有環,找到入環的第乙個結點

解:第一步判斷單鏈表是否有環:需要設定快慢指標,慢指標p一次走乙個(p=p->next)

快指標q一次走兩個(q=q->next->next),當p和q相等時說明單鏈表有環。

第二步找到入環的第乙個結點:

x為從頭到入環的第乙個結點的路徑,y為入環結點到pq相等處的路徑,z為pq相等處向後走到入環結點的路徑;

p的路徑:x+y; q的路徑:x+(y+z)n+y;

找關係:2(x+y)=x+(y+z)n+y->x+y=(y+z)n->x=(y+z)(n-1)迴圈路徑+z->x=z;

即p從頭開始走,q從pq相等處開始走,pq相等處即為入環結點。(注意此時的p和q都是一次走乙個);

帶頭結點的單鏈表

include include define error printf struct node typedef int elementtype typedef struct node list typedef struct node node struct node list initialize ...

帶頭結點的單鏈表

帶頭節點的單鏈表 include include using namespace std typedef struct listnode node,pnode 新建結點,num表示結點個數 pnode newnode int num pnode temp head temp next null fo...

單鏈表(帶頭結點)

按照自己的想法和思路寫了一下帶頭結點的單鏈表,並進行了測試,畢竟自己能力有限,可能有的地方沒有測試到,還可能存在一些潛在的錯誤。標頭檔案 include using namespace std typedef struct node node,link typedef struct list lis...