链表的基本操作C/c++

来源:互联网 发布:股票分时预警软件 编辑:程序博客网 时间:2024/06/14 07:08
#include <iostream>#include <stack>#include <set>using namespace std;struct ListNode{int data;ListNode* next;};typedef ListNode List;struct dListNode{int data;dListNode* next;dListNode* previous;};typedef dListNode dList;//头插法建立双向链表,与单链表类似void createDListHead(dList* &L){L = new dList;L->next = L->previous = NULL;int val;cin >> val;while (val != -1){dListNode* p = new dList;p->next = L->next;p->previous = L;p->data = val;L->next = p;cin >> val;}}//尾插法建立双向链表,与尾插法类似void createDListRear(dList* &L){L = new dList;L->next = L->previous = NULL;int val;cin >> val;dListNode* q = L;while (val != -1){dListNode* p = new dList;p->data = val;p->previous = q;p->next = NULL;q->next = p;q = p;cin >> val;}}//删除指定值的节点,例如3->1->2->3->3->4->3,输入3,结果为1->2->4;void deleteDLNode(dList* L){int val;cout << "Please input the val you want to delete:  ";cin >> val;dListNode* p = L;dListNode* q = NULL;while (p->next != NULL){if (p->next->data == val){q = p->next;if (p->next->next!=NULL)//与单向链表不同之处,不要忘记加判断是否为空指针p->next->next->previous = p;p->next = q->next;delete q;}elsep = p->next;}}//尾插法建立单链表void createListRear(List* &L){L = new List;L->next = NULL;ListNode* q = L;int val;cin >> val;while (val != -1){ListNode * p = new List;p->data = val;p->next = NULL;q->next = p;q = p;cin >> val;}return;}//头插法建立单链表void createListHead(List* &L){L = new List;L->next = NULL;int val;cin >> val;while (val != -1){ListNode* p = new List;p->data = val;p->next = L->next;L->next = p;cin >> val;}return;}//打印链表template<typename T>void printList(T *L){T* p = L->next;while (p != NULL){cout << p->data << " -> ";p = p->next;}cout << "NULL" << endl;return;}//反转单链表,遍历链表,依次头插void reverseList(List* L){ListNode* p = L->next;ListNode* r = p;//不要忘记记录头结点,循环结束后将它的next置为NULL 否则会形成环;if (p == NULL) return;//同时不要忘记判断链表是否为空,否则r=L->next;r->next=NULL;会使程序崩溃;while (p != NULL){ListNode* q = p->next;p->next = L->next;L->next = p;p = q;}r->next = NULL;return;}//删除倒数第k个节点,快指针先走k,慢指针再走,快指针到达链表尾部时,慢指针到达倒数第K个节点void getKthFromRear(List* L,int k){ListNode* fast = L->next;ListNode* slow = L->next;if (L->next == NULL||k<=0) return;int i = 1;while (i < k)//此处可借可k=1考虑;{fast = fast->next;if (fast == NULL)//当K大于链表长度时,为K%Len;fast = L->next;++i;}while (fast->next != NULL)//判断条件为fast->next==NULL,若为fast==NULL,则上个while条件为i<=k{fast = fast->next;slow = slow->next;}cout << "The Kth from rear is: " << slow->data << endl;return;}//获取中间节点void getMid(List* L){if (L->next == NULL) return;ListNode* fast = L->next;ListNode* slow = L->next;while (fast->next!= NULL&&fast->next->next!=NULL)//fast fast->next当Len为奇数时返回Len/2+1;fast->next,fast->next->next返回Len/2;{fast = fast->next->next;slow = slow->next;}cout << "Mid element is: " << slow->data << endl;}//逆序打印,采用栈void printFromRear(List* L){stack<int> iSak;ListNode* p = L->next;cout << "NULL" << " <- ";while (p != NULL){iSak.push(p->data);p = p->next;}while (!iSak.empty()){cout << iSak.top() << " <- ";iSak.pop();}cout << "Head" << endl;}//删除data=val的节点void deleteElementK(List* L){if (L->next == NULL) return;cout << "Plese input the value you want to delete: ";int val;cin >> val;ListNode* p = L;ListNode* r = L;while (p->next!= NULL)//要记录前一个节点,故要用p->next来判断;{if (p->next->data == val){r = p->next;p->next = r->next;delete r;//continue;}else//不要忽略else,否则出现连续的值得时候不能完全删除p = p->next;//p = p->next;}}//合并两个有序链表,到L1void mergeSortList(List *L1, List* L2){if (L1->next == NULL){L1->next = L2->next;return;}if (L2->next == NULL) return;ListNode* p1 = L1->next;ListNode* p2 = L2->next;ListNode* q = NULL;if (p1->data < p2->data)//先找到两个链表中第一个较小的节点,让q指向它,不要忘记q=p1后面一句{q = p1;p1 = p1->next;}else{q = p2;p2 = p2->next;}L1->next = q;while (p1 != NULL&&p2 != NULL){if (p1->data < p2->data){q->next = p1;q = p1;p1 = p1->next;}else{q->next = p2;q = p2;p2 = p2->next;}}if (p1 != NULL)q->next = p1;else if (p2 != NULL)q->next = p2;}//用于测试,构造有环链表,输入一个链表中的节点数据,形成环,例如1->4->6->8->5,输入6,会使5的下一个节点为6,形成环void makeListWithCircle(List* L){ListNode* p = L->next;ListNode* c = NULL;cout << "Please input the value to be circle:";int val;cin >> val;while (p->next != NULL){if (p->data == val&&c==NULL)c = p;p = p->next;}p->next = c;}//判断链表是否有环bool hasCircle(List *L){ListNode* p = L->next;ListNode* q = L->next;while (p->next != NULL&&p->next->next != NULL){p = p->next->next;q = q->next;if (p == q)return true;}return false;}//找到环的起点,用set容器存储已经遍历过的节点,每次遍历一个新节点就检查是否存在于set里,实现较简单void findTheCircleBegin(List *L){ListNode* p = L->next;set<List*> listSet;while (p != NULL){if (listSet.count(p) == 0)listSet.insert(p);else{cout << p->data << endl;return;}p = p->next;}cout << "Has No Crcle!" << endl;}//找到两个相交链表的第一个交点,若链表相交,则尾节点必相同,求出两个链表长度的差k,让长的链表先走k步,然后连个链表再一起走,相等时即为第一个节点void findIntersectPos(List* L1, List* L2){ListNode* p1 = L1->next;ListNode* p2 = L2->next;int lenth1 = 1;int lenth2 = 1;while (p1->next != NULL){p1 = p1->next;++lenth1;}while (p2->next!=NULL){p2 = p2->next;++lenth2;}if (p1 != p2){cout << "Not Intersect!" << endl;return;} p1 = L1->next;p2 = L2->next;int k = abs(lenth1 - lenth2);int i = 1;if (lenth1 >= lenth2){while (i <= k){p1 = p1->next;++i;}}else{while (i <= k){p2 = p2->next;++i;}}while (p2 != p1){p2 = p2->next;p1 = p1->next;}cout << p1->data << endl;}//构造用于测试的相交链表,让L2的尾节点指向L1的某一节点void makeIntersect(List* L1, List* L2){ListNode* p1 = L1->next;ListNode* p2 = L2->next;while (p2->next != NULL)p2 = p2->next;int val;cout << "Please input the value of the intersect:  ";cin >> val;while (p1 != NULL){if (p1->data == val)break;p1 = p1->next;}p2->next = p1;}/*int main(){char q;//cin >> q;cout << "please input the datas of list, -1 to end" << endl;while (1){//List *L1 = NULL;//List* L2 = NULL;//createListRear(L1);//createListRear(L2);dList* dL1 = NULL;dList* dL2 = NULL;createDListHead(dL1);createDListRear(dL2);//mergeSortList(L1, L2);//getKthFromRear(L1, 1);//getMid(L1);//reverseList(L1);//printList(L1);//printList(L2);//deleteElementK(L1);//deleteElementK(L2);printList(dL1);printList(dL2);deleteDLNode(dL1);deleteDLNode(dL2);printList(dL1);printList(dL2);//cout << hasCircle(L1) << endl;//findTheCircleBegin(L1);//makeListWithCircle(L1);//cout << hasCircle(L1) << endl;//findTheCircleBegin(L1);//printFromRear(L1);//findIntersectPos(L1, L2);//makeIntersect(L1, L2);//createDListRear(dL1);//deleteDLNode(dL1);//createDListRear(dL2);//printList(dL1);//printList(dL2);//printList(L2);//findIntersectPos(L1, L2);cout << "Do you want to quit? (y/n)" << endl;cin >> q;if (q == 'y') break;else cout << "please input the datas of list, -1 to end" << endl;}//printList(L2);return 0;}*/

0 0
原创粉丝点击