用C++语言实现链表面试题

来源:互联网 发布:java技术支持工程师 编辑:程序博客网 时间:2024/06/05 10:25
#include <iostream>#include <assert.h>#include <malloc.h>#include <stack>using namespace std;typedef int DataType;typedef struct Node{DataType data;struct Node* next;}Node,*pNode,*pList;void Init(pList* head){*head = NULL;}void PushBack(pList* head,DataType x)//尾插{Node* cur = *head;Node* p = (Node*)malloc(sizeof(Node));p->data = x;p->next = NULL;if (cur == NULL)//空链表{*head = p;}else{while (cur->next)//非空链表{cur = cur->next;}cur->next = p;}}//逆序打印链表void PrintfromTail1(pNode head){//1.数组//2.逆序---->正向打印---->逆序//3.递归if (head){PrintfromTail1(head->next);cout << head->data<<"--->";}}//递归转循环void PrintfromTail2(pNode head){if (head == NULL)return;stack<Node*> s;Node* cur = head;while (cur){s.push(cur);cur = cur->next;}while (!s.empty()){cur = s.top();cout << cur->data << " ";s.pop();}cout << endl;}void Print(pNode head)//正序打印{pNode cur = head;for (; cur!=NULL; cur = cur->next){cout << cur->data << " ";}cout << endl;}size_t size(pNode head){pNode cur = head;size_t count = 0;while (cur){cur = cur->next;count++;}return count;}pNode Find(pNode head,size_t pos){assert(pos >= 0 && pos <= size(head));pNode cur = head;if (head == NULL)return NULL;else{for (size_t i = 0; i < pos; i++){cur = cur->next;}}return cur;}//删除无头单链表的非尾结点void DelteNoTail(pNode head, int pos){pNode p=Find(head, pos);pNode Del = p->next;swap(p->data, Del->data);p->next = Del->next;delete Del;}//在无头单链表的一个非头结点前插入一个结点void InsertNoHead(pNode head, int pos,DataType data){pNode p = Find(head, pos);pNode pnext = p->next;pNode NewNode = new Node;NewNode->data = data;p->next = NewNode;NewNode->next = pnext;swap(p->data, NewNode->data);}pNode Back(pNode head)//找到最后一个元素{if (head == NULL)return NULL;pNode cur = head;while (cur->next){cur = cur->next;}return cur;}//单链表实现约瑟夫环pNode JosephCircle(pNode head, int M){//构环pNode Tail = Back(head); pNode cur = head;Tail->next = head;while (cur->next!=cur){int N = M;//重要while (--N)//报数{cur = cur->next;}cout << cur->data<<" ";//替换删除pNode Del = cur->next;cur->data = Del->data;cur->next = Del->next;delete Del;}cout << endl;cur->next = NULL;head = cur;return cur;}//逆置/反转单链表//1.三个指针pNode Reverse(pNode& head){//空链表,只有一个结点的链表if (head==NULL || head->next==NULL)return head;pNode pPre = NULL;pNode pCur = head;pNode pNext = head->next;while (pNext){pCur->next = pPre;pPre = pCur;pCur = pNext;pNext = pCur->next;}pCur->next = pPre;head = pCur;}//头插逆置pNode ReverList(pNode& head){pNode pCur = head;pNode pCurNext = NULL;pNode Newhead = NULL;while (pCur){pCurNext = pCur->next;pCur->next = Newhead;Newhead = pCur;pCur = pCurNext;}return Newhead;}//单链表排序void BubbleSort(pNode head){if (head == NULL || head->next == NULL)return;pNode pCur = head;pNode pNext = pCur->next;pNode pTail = NULL;bool ischange = false;while (pTail != head){pCur = head;pNext = pNext->next;ischange = false;//标志,检查是否发生交换while (pNext){if (pCur->data > pNext->data){swap(pCur->data, pNext->data);ischange = true;}pCur = pNext;pNext = pNext->next;}pTail = pCur;if (!ischange)//没有交换return;}}//合并两个有序链表,合并后仍有序pNode Merge2List(pNode phead1, pNode phead2){pNode L1 = phead1;pNode L2 = phead2;pNode pNewNode = NULL;pNode pTail = NULL;//有一个为空if (L1 == NULL)return L2;if (L2 == NULL)return L1;//设置第一个头指针的位置在head1还是head2的位置if (L1->data <= L2->data){pNewNode = L1;pTail = pNewNode;L1 = L1->next;}else{pNewNode = L2;pTail = pNewNode;L2 = L2->next;}//比较,每次比较小的尾插在新链表中while (L1&&L2){if (L1->data <= L2->data){pTail->next = L1;L1 = L1->next;}else{pTail->next = L2;L2 = L2->next;}pTail = pTail->next;}//一个链表走到尾,另一个链表直接连接在新链表的尾部if (L1)pTail->next = L1;if (L2)pTail->next = L2;return pNewNode;}//查找中间结点pNode MidNode(pNode head){pNode fast = head;pNode slow = head;pNode cur = head;if (head == NULL||head->next==NULL)return head;//while (fast)//{//fast = fast->next->next;//slow = slow->next;//}//return slow;//偶数返回中间的后一个while (fast->next&&fast->next->next){fast = fast->next->next;slow = slow->next;}return slow;}//删除倒数第k个结点void DelRekNode(pNode head, size_t k){pNode fast = head;pNode slow = head;pNode cur = NULL;pNode Del = NULL;if (NULL == head || k == 0)//链表为空或k为0return;while (k--)//快指针先走k步{fast = fast->next;}while (fast->next){fast = fast->next;slow = slow->next;}cur = slow;//cur指向要删除结点的前一个结点Del = cur->next;cur->next = Del->next;delete Del;}/*//判断链表是否带环bool IsCricle(pNode head){pNode fast = head;pNode slow = head;while (fast&&slow){if (fast == slow)return true;elsereturn false;fast = fast->next->next;slow = slow->next;}}*///判断是否带环,返回两个指针相遇位置pNode IsCricle(pNode head){pNode fast = head;pNode slow = head;while (fast && slow&&fast->next){fast = fast->next->next;slow = slow->next;if (fast == slow)return fast;}return NULL;}//求环的长度size_t LenofCricleList(pNode head){pNode meet = IsCricle(head);assert(meet);int count = 1;pNode cur =meet;while (cur->next!=meet){cur = cur->next;count++;}return count;}//求环入口地址pNode ExtofCircle(pNode head){pNode meet = IsCricle(head);assert(meet);pNode cur = head;while (cur!=meet){meet = meet->next;cur = cur->next;}return cur;}size_t LenNoCircle(pNode head){size_t len = 0;while (head){head = head->next;len++;}return len;}//判断两链表是否相交,若相交,求交点pNode CheckCross(pNode head1, pNode head2){pNode cur1 = head1;pNode cur2 = head2;//两个链表均不带环if ((!IsCricle(head1)) && (!IsCricle(head2))){size_t len1 = LenNoCircle(head1);size_t len2 = LenNoCircle(head2);if (len1 > len2){//头指针为head1的链表先走len2-len1步for (int i = 0; i < len2 - len1; i++){cur1 = cur1->next;}}if (len1>len2){for (size_t i = 0; i <= len1 - len2; i++){cur2 = cur2->next;}}//两个指针一起走while ((NULL != cur1) && (NULL != cur2)){cur1 = cur1->next;cur2 = cur2->next;if (cur1 == cur2)return cur1;}}//两个链表均带环else if (IsCricle(head1) && IsCricle(head2)){//交点在环外pNode ex1 = ExtofCircle(head1);pNode ex2 = ExtofCircle(head2);if (ex1 == ex2){//两个链表环外的部分的长度ex1->next = NULL;ex2->next = NULL;size_t len1 = LenNoCircle(head1);size_t len2 = LenNoCircle(head2);while (len1 < len2){for (size_t i = 0; i < len1 - len2; i++){cur2 = cur2->next;}}while (len1>len2){for (size_t i = 0; i < len2 - len1; i++){cur1 = cur1->next;}}while (NULL != cur1&&NULL != cur2){cur1 = cur1->next;cur2 = cur2->next;if (cur1 == cur2)return cur1;}}else{return ex1;}}//其他情况return NULL;}int main(){Node* head0 = NULL;//不带环Init(&head0);PushBack(&head0, 1);PushBack(&head0, 4);PushBack(&head0, 6);PushBack(&head0, 8);pNode tail = Back(head0);Node* head1 = NULL;//不带环Init(&head1);PushBack(&head1, 1);PushBack(&head1, 3);pNode mid = Back(head1);PushBack(&head1, 5);PushBack(&head1, 7);tail->next = mid;pNode p=CheckCross(head0, head1);cout << p << endl;Node* head2 = NULL;//带环Init(&head2);PushBack(&head2, 2);PushBack(&head2, 3);PushBack(&head2, 7);PushBack(&head2, 9);pNode pTail = Back(head2);pTail->next = head2;//Print(head);//DelteNTail(head, 1);//Print(head);//InsertNoHead(head, 2,10);//Print(head);//JosephCircle(head, 2);//Reverse(head);//Print(head);//pNode p =ReverList(head);//Print(p);//BubbleSort(head);//Print(head);//pNode p=Merge2List(head, head1);//Print(p);//pNode mid = MidNode(head);//cout << mid->data << endl;//DelRekNode(head, 3);//Print(head);//if (IsCricle(head1))//cout << "1" << endl;//else//cout << "-1" << endl;//int len = LenofCricleList(head1);//cout << len << endl;//ExtofCircle(head1);system("pause:");return 0;}

原创粉丝点击