新增連結串列節點、連結串列的倒序查詢、列印
阿新 • • 發佈:2021-11-18
1.其實用的是快慢指標,來倒查某個元素。
#include<iostream> #include<stdlib.h> #include<stack> using namespace std; typedef int USER_TYPE;//連結串列中資料使用者可以只在這裡修改就可以完成 //連結串列結構 struct ListNode { USER_TYPE data; ListNode* pNext; }; typedef struct ListNode ListNode; //建立一個連結串列結點 ListNode* createListNode(int value) { ListNode *pNode = new ListNode(); pNode->data = value; pNode->pNext = NULL; return pNode; } //遍歷連結串列中的所有結點 void printList(ListNode* pHead) { ListNode *pNode = pHead; while (pNode != NULL) { cout << pNode->data << " "; pNode = pNode->pNext; } cout << endl; } //輸出連結串列中的某一結點的值 void printListNode(ListNode* pNode) { if (pNode == NULL) { printf("The node is NULL\n"); } else { printf("The key in node is %d.\n", pNode->data); } } //往連結串列末尾新增結點 /* 注意這裡pHead是一個指向指標的指標,在主函式中一般傳遞的是引用。 因為如果要為連結串列新增結點,那麼就會修改連結串列結構,所以必須傳遞引用才能夠儲存修改後的結構。 */ void addToTail(ListNode** pHead, int value) { ListNode* pNew = new ListNode();//新插入的結點 pNew->data = value; pNew->pNext = NULL; if (*pHead == NULL)//空連結串列 { *pHead = pNew; } else { ListNode* pNode = *pHead; while (pNode->pNext != NULL) pNode = pNode->pNext; pNode->pNext = pNew; } } //對空指標等輸入進行判斷,魯棒性更好 ListNode* findKthNodeFromEnd2(ListNode* pHead, int k) { if (pHead == NULL || k == 0) //判斷指標為空 k == 0的情況; return NULL; ListNode* pNode = pHead;//當前結點 ListNode* pKthNode = pHead;// while (k - 1 > 0) { if (pNode->pNext != NULL) //判斷 k-1<0的情況 { pNode = pNode->pNext;//讓pNode先走k-1步,快慢指標 --k; } else return NULL; } while (pNode->pNext != NULL) { pNode = pNode->pNext; pKthNode = pKthNode->pNext; } return pKthNode; } void main() { //建立結點 ListNode* pNode1 = createListNode(1);//建立一個結點 printList(pNode1);//列印 //往連結串列中新增新結點 addToTail(&pNode1, 22);//為連結串列新增一個結點,傳入地址用於指標間接修改node之和list addToTail(&pNode1, 33);//為連結串列新增一個結點 addToTail(&pNode1, 44);//為連結串列新增一個結點 addToTail(&pNode1, 55);//為連結串列新增一個結點 addToTail(&pNode1, 66);//為連結串列新增一個結點 addToTail(&pNode1, 77);//為連結串列新增一個結點 //列印連結串列 printList(pNode1);//列印 //返回第二個指標指向的加點,該節點就是倒數第k個數字 ListNode* KthNode = findKthNodeFromEnd2(pNode1, 2); printListNode(KthNode); system("pause"); }
2.單鏈表逆序的四種思路(陣列,棧,逆序連結串列,遞迴)
/************************************************************************* > Function: 連結串列逆序的四種思路(陣列,棧,逆序連結串列,遞迴) ************************************************************************/ #include <iostream> #include <vector> #include <stack> #include <stdlib.h> #include <time.h> using namespace std; struct Node { int data; Node *next; }; //寫一個連結串列類,實現四種連結串列逆序列印方式(陣列,棧,逆序連結串列,遞迴) class LinkList { public: LinkList(){head = new(Node);head->next = NULL;} void setRandList(int len); //生成len個隨機數並插入連結串列 void insert(int i,int index = 1); //插入,可指定位置,預設頭插 void print() const; //列印 void invertPrint_vector() const;//使用陣列,不改變連結串列本身 void invertPrint_stack() const;//使用棧,不改變連結串列本身 void invertprint_linklist();//直接逆序連結串列 void invertprint_recursion() const;//遞迴列印,不改變連結串列本身 void invertprint_recursion(Node * node) const; //遞迴時需傳參呼叫該函式 private: Node * head; int length = 0; }; void LinkList::setRandList(int len) { srand((unsigned)time(NULL)); for(int i = 0;i < len; i++) { insert(rand()%99+1); } } void LinkList::insert(int data,int index) { if(index > length + 1) { throw "位置出錯!"; } else { Node *p = head; for(int i = 1; i < index; i++) { p = p->next; } Node *newnode = new Node; newnode->data = data; newnode->next = p->next; p->next = newnode; length++; } } void LinkList::print() const { if(NULL == head->next){return;} cout << "\n當前正序輸出:"; Node *p = head->next; while(NULL != p) { cout << p->data << " "; p = p->next; } cout << endl; } void LinkList::invertPrint_vector() const { if(NULL == head->next){return;} cout << "陣列倒序:"; vector<int> v; Node *p = head->next; while(NULL != p) { v.emplace_back(p->data); p = p->next; } for(auto it = v.end() - 1; it >= v.begin(); it--) { cout << *it << " "; } cout << endl; } void LinkList::invertPrint_stack() const { if(NULL == head->next){return;} cout << "棧 倒 序:"; stack<int> s; Node *p = head->next; while(NULL != p) { s.push(p->data); p = p->next; } while(!s.empty()) { cout << s.top() << " "; s.pop(); } cout << endl; } void LinkList::invertprint_linklist() { if(NULL == head->next){return;} cout << "逆序連結串列(此處使用方法執行過程不列印):\n"; Node *p = new(Node); p->next = head->next; Node *q = new(Node); q->next = p->next->next; head->next->next = NULL;//必須置空,否則尾節點自迴圈列印會出錯 head->next = q->next->next; for(int i = 1; i < length - 2; i++) { q->next->next = p->next; p->next = q->next; q->next = head->next; head->next = head->next->next; } q->next->next = p->next; head->next->next = q->next; delete p; delete q; } void LinkList::invertprint_recursion() const { if(NULL == head->next){return;} cout << "遞迴倒序:"; invertprint_recursion(head); //本笨蛋目前沒想到更好的用一個函式解決該遞迴的方法,預設引數為head會報錯。 //如有大佬,請教我! cout << endl; } void LinkList::invertprint_recursion(Node * node) const { if(NULL == node->next) { return; } invertprint_recursion(node->next); cout << node->next->data << " "; //在這裡要說明的是,如果把列印放在遞迴呼叫前,可以實現正序列印連結串列 } int main() { LinkList ll; ll.setRandList(10); ll.print(); ll.invertPrint_vector(); ll.print(); ll.invertPrint_stack(); ll.print(); ll.invertprint_linklist1(); ll.print(); ll.invertprint_recursion(); ll.print(); ll.invertprint_recursion(); ll.print(); return 0; }
轉載:https://blog.csdn.net/qq_54676460/article/details/119832471