您好,登錄后才能下訂單哦!
這篇文章主要介紹了c#如何實現單向鏈表的查刪改功能,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
slist.h//頭文件
#ifndef _SLIST_H_ #define _SLTST_H_ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> typedef int SLTDataType; typedef struct SListNode { SLTDataType data; struct SListNode* next; }SListNode; void SListInit(SListNode** pphead); void SListDestory(SListNode** pphead); SListNode* BuySListNode(SLTDataType x); void SListPushFront(SListNode** pphead, SLTDataType x); void SListPopFront(SListNode** pphead); SListNode* SListFind(SListNode* pphead, SLTDataType x); // 在pos的后面進行插入 void SListInsertAfter(SListNode* pos, SLTDataType x); // 在pos的前面進行插入 void SListEraseAfter(SListNode* pos); void SListRemove(SListNode** pphead, SLTDataType x); void SListRemoveAll(SListNode** pphead, SLTDataType x); void SListPrint(SListNode* pphead); void SListReverse(SListNode **pphead); void SListReverse2(SListNode **pphead); SListNode* getIntersectionNode(SListNode* headA, SListNode*headB); SListNode *detectCycle(SListNode *head); #endif
slist.c//源文件
#include"slist.h" void SListInit(SListNode** pphead)//初始化 { *pphead = NULL; } void SListDestory(SListNode** pphead) { if (*pphead == NULL) { return; } else { while ((*pphead)->next) { SListEraseAfter(*pphead); } free(*pphead); *pphead = NULL; } } SListNode* BuySListNode(SLTDataType x) { SListNode* res = (SListNode *)malloc(sizeof(SListNode)); res->data = x; res->next = NULL; return res; } void SListPushFront(SListNode** pphead, SLTDataType x) { SListNode* tmp = BuySListNode(x); tmp->next = *pphead; *pphead = tmp; } void SListPopFront(SListNode** pphead) { if (*pphead == NULL) { return; } /*(*pphead)->date = (*pphead)->next;*/ SListNode* tmp = (*pphead)->next; free(*pphead); *pphead = tmp; } SListNode* SListFind(SListNode* pphead, SLTDataType x)//找x數據 { SListNode* tmp; for (tmp = pphead; tmp; tmp = tmp->next) { if (tmp->data == x) { return tmp; } return NULL; } } void SListInsertAfter(SListNode* pos, SLTDataType x)//把x插到pos后面 { SListNode* tmp = BuySListNode(x); tmp->next = pos->next; pos->next = tmp; } void SListEraseAfter(SListNode* pos)//刪除pos后面的數據 { SListNode* tmp = pos->next; if (tmp == NULL) { return; } pos->next = tmp->next; free(tmp); } void SListRemove(SListNode** pphead, SLTDataType x)//移除x { SListNode* tmp; if (*pphead == NULL) { return; } if ((*pphead)->data==x) { SListPopFront(*pphead); } else { for (tmp = *pphead; tmp->next; tmp = tmp->next) { SListEraseAfter(pphead); return; } } } void SListRemoveAll(SListNode** pphead, SLTDataType x) { SListNode* tmp; if (*pphead && (*pphead)->data == x) { SListPopFront(*pphead); } for (; tmp = *pphead; tmp&&tmp->next) { if (tmp->next == x) { SListEraseAfter(tmp); } else { tmp = tmp->next; } } } void SListPrint(SListNode* pphead) { SListNode* cur; printf("pphead->"); for (cur = pphead; cur; cur = cur->next) { printf("%d->", cur->data); } printf("NULL\n"); } void SListReverse(SListNode **pphead)//反轉鏈表 { SListNode *head = *pphead; //此指針在每次循環中始終指向當前鏈表的頭 SListNode *tmp = head->next; //此指針在每次循環中始終指向要被后刪頭插的節點 SListNode *oldh = *pphead; //此指針在每次循環中始終指向原本的頭結點,不會改變指向 while (tmp) //如果tmp為空,則代表逆序結束,舊頭的next已經是空的了,成為新鏈表的末尾 { oldh->next = tmp->next; //將tmp架空,實際是后刪操作的一部分 tmp->next = head; //讓tmp變成新的頭,實際是頭插操作的一部分 head = tmp; //換頭 tmp = oldh->next; //讓tmp變成下次循環中待刪除的節點 } *pphead = head; } void SListReverse2(SListNode **pphead)//反轉鏈表 { SListNode *pre = *pphead; //被執行操作的前一個節點 SListNode *cur = pre->next; //被執行操作的節點 SListNode *next = cur; //被執行操作的后一個節點,暫時指在cur,在循環開始的時候跳轉到其后一個節點 pre->next = NULL; //此時的頭,將會是轉換后的尾,這里是在設置鏈表尾節點 while (next) { next = next->next; //先讓next變成下一個節點,之所以不放在最后,是因為會有next為空的限制 cur->next = pre; //讓原本指著后面的指到前面來(先后轉) pre = cur; //為了下次循環而傳遞數據,這里是設置下次循環的上一個節點(本次執行操作的節點將會成下次循環的上一個節點) cur = next; //同上(本次的下一個節點將會成為下次的被執行節點) } *pphead = pre; //循環跳出后cur和next都已經指向空了,pre才是新的頭 } //輸入兩個鏈表,找出它們的第一個公共結點 SListNode* getIntersectionNode(SListNode* headA, SListNode*headB) { int lenA = 0; int lenB = 0; int gap, i; SListNode* cur = 0; SListNode * longerlist = headA; SListNode * shorterlist = headB; for (cur = 0; cur; cur = headA->next) { lenA++; } for (cur = 0; cur; cur = headB->next) { lenB++; } gap = abs(lenA - lenB); if (lenA > lenB) { longerlist = headA; shorterlist = headB; } else { longerlist = headB; shorterlist = headA; } for (i = 0; i < gap; i++) { longerlist=longerlist->next; } for (; longerlist&&shorterlist; longerlist = longerlist->next, shorterlist = shorterlist->next) { if (longerlist == shorterlist) { return longerlist; } } return NULL; } // 給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回 NULL SListNode *detectCycle(SListNode *head) { SListNode * fast = head; SListNode * slow = head; while (fast && slow && fast->next) { fast = fast->next->next;//遍歷速度為2 slow = slow->next;//遍歷速度為1 if (fast == slow)//判斷兩不同遍歷速度的交點 { break; } } for (; fast && fast->next; fast = fast->next, head = head->next)//交點到入環的第一個節點距離等于頭節點到入環的第一個節點 { if (fast == head) { return fast; } } return NULL; }
main.c//測試
#include"slist.h" #if 0 //1,選擇程序段 int main()//測試 { SListNode *phead1; //SListNode *phead2; SListNode *tmp; SListNode *tmp2; SListInit(&phead1); //SListInit(&phead2); SListPushFront(&phead1, 8); tmp = phead1; SListPushFront(&phead1, 7); SListPushFront(&phead1, 6); SListPushFront(&phead1, 5); SListPushFront(&phead1, 4); SListPushFront(&phead1, 3); tmp2 = phead1; SListPushFront(&phead1, 2); SListPushFront(&phead1, 1); tmp->next = tmp2; //phead2->next = phead1->next->next; SListNode * ret = detectCycle(phead1); if (ret) { printf("%d\n", ret->data); } else { printf("NULL\n"); } //SListDestory(&phead1); //SListDestory(&phead2); return 0; } #else int main()//測試 { SListNode *phead; SListInit(&phead); SListPushFront(&phead, 1); SListPushFront(&phead, 2); SListPushFront(&phead, 3); SListPushFront(&phead, 4); SListPushFront(&phead, 5); SListPushFront(&phead, 6); SListPushFront(&phead, 7); SListPushFront(&phead, 8); SListPushFront(&phead, 9); //SListPopFront(&phead); //SListPopFront(&phead); /* SListInsertAfter(SListFind(phead, 6), 9); SListEraseAfter(SListFind(phead, 4)); SListRemove(&phead, 7); SListPrint(phead); */ //SListRemoveAll(&phead, 8); SListReverse2(&phead); SListPrint(phead); SListDestory(&phead); //SListPrint(phead); return 0; } #endif //int main()//約瑟夫環問題,鏈表解決 //{ // SListNode *phead; // SListNode *plast; // SListNode *cur; // int m = 11, n = 3; // int i; // SListInit(&phead); // SListPushFront(&phead, m); // plast = phead; // for (i = m - 1; i >= 1; i--) // { // SListPushFront(&phead, i); // } // plast->next = phead; // cur = plast; // for (; m > 1; m--) // { // for (i = 1; i < n; i++) // { // cur = cur->next; // printf("%d號報數字%d\n", cur->data, i); // } // printf("%d號被去掉\n", cur->next->data); // SListEraseAfter(cur); // } // printf("%d號最終獲勝\n", cur->data); // free(cur); // return 0; //}
感謝你能夠認真閱讀完這篇文章,希望小編分享的“c#如何實現單向鏈表的查刪改功能”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。