c語言實現簡單單鏈表
阿新 • • 發佈:2019-01-25
1.比較順序表和連結串列的優缺點,說說他們正在什麼場景下使用?
答:
對於順序表,無論是動態還是靜態,他們有都會死連續的儲存空間,在讀取時間效率上比較短,但在插入和刪除時會比較麻煩,需要不斷的遍歷去找到尾節點。
對於連結串列,因為是鏈式儲存。因此在需要的時候我們才在堆上進行開闢空間,連結串列對於插入刪除比較簡單,但是遍歷需要多次跳轉。
對於空間申請方式:
順序表,空間開闢是在順序表空間已滿時開闢,開闢次數較多時會出現較大的空間浪費。
對於連結串列,空間是針對單個節點的,不存在多餘的空間浪費。並且在碎片空間池的機制下,有效利用碎片空間。
所以,順序表一般用於查詢遍歷操作比較頻繁的情況下進行使用,連結串列則針對於資料刪除修改比較頻繁的資料使用。
2.從未到頭列印單鏈表
void PrintNodeTailToHead(ListNode *head)
{
if (head)
{
while (head->next)
{
PrintNodeTailToHead(head->next);
}
}
printf("%d->",head->data);
}
3.刪除一個無頭單鏈表的非尾節點
void DelNoTail(ListNode*plist)
{
ListNode*del = plist->next;
plist-> data = del->data;
plist->next = del->next;
free(plist);
plist = NULL;
}
4.在無頭單鏈表的一個節點前程插入一個節點
void Insert(ListNode** ppList, ListNode* pos, DataType x)
{
if ((*ppList) == NULL)
{
*ppList = BuyNode(x);
}
else
{
ListNode *cur = BuyNode(x);
cur->next = pos->next;
pos->next = cur;
}
}
5.單鏈表實現約瑟夫環
DataType JLink(ListNode**pplist)
{
ListNode *cur = *pplist;
while ((*pplist)->next)
{
ListNode *del = *pplist;
del = (*pplist)->next->next->next;
*pplist = del;
free(del);
del = NULL;
}
return (*pplist)->data;
}
6.逆置/ 反轉單鏈表
void _Reversre(ListNode*plist)//遞迴
{
ListNode *cur = plist;
ListNode *prev = plist;
while (cur->next)
{
prev = cur;
cur = cur->next;
}
cur->next = prev;
}
void reverse(ListNode**listhead)//非遞迴
{
if ((NULL == (*listhead)) || (NULL == ((*listhead)->next)))
return; //邊界檢測
ListNode* ppre = *listhead; //先前指標
ListNode* pcur = ppre->next; //當前指標
ListNode* pnext = NULL; //後繼指標
while (pcur != NULL)
{
pnext = pcur->next;
pcur->next = ppre;
ppre = pcur;
pcur = pnext;
}
(*listhead)->next = NULL;
(*listhead) = ppre; //記錄下新的頭結點
}
7.單鏈表排序(氣泡排序)
void sort(ListNode*plist)
{
//冒泡
ListNode *max=plist;
DataType tmp;
while (max->next)
{
if ((max->data) < plist->data)
{
tmp = max->data;
max->data = plist->data;
plist->data = tmp;
}
else
plist = plist->next;
if (plist->next == NULL)
{
max = max->next;
}
}
}
8.合併兩個有序連結串列,合併後依然有序
ListNode Merge(ListNode* head1, ListNode* head2)
{
ListNode* newhead = NULL;
if (head1->data < head2->data)
{
newhead = head1;
head1 = head1->next;
newhead->next = Merge(head1, head2);
}
if (head1->data>head2->data)
{
newhead = head2;
newhead->next = Merge(head1, head2->next);
}
}
9.查詢單鏈表的中間節點,要求只遍歷一遍
ListNode FindMid(ListNode*plist)
{
ListNode *slow = plist;
ListNode *fast = plist;
while (fast)
{
fast = fast->next->next;
slow = slow->next;
}
return *slow;
}
10.查詢單鏈表的倒數第K個節點,要求只遍歷一遍
ListNode FindReNum(ListNode*plist, int k)
{
ListNode*fast = plist;
ListNode*slow = plist;
while (k--)
{
fast=fast->next;
}
while (fast)
{
fast = fast->next;
slow = slow->next;
}
return *slow;