使用C++语言解决常见的数据结构面试题
一、链表和顺序表
1.从尾到头打印单链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
class {public : vector <int > printListFromTailToHead(ListNode* head) { ListNode* cur = nullptr ; ListNode* tail = nullptr ; vector <int > ArrayList; while (tail != head) { cur = head; while (cur->next != tail) { cur = cur->next; } tail = cur; ArrayList.push_back(tail->val); } return ArrayList; } }; class {public : vector <int > printListFromTailToHead(ListNode* head) { vector <int > ArrayList; stack <int > stacknode; ListNode* cur = head; while (cur != NULL ) { stacknode.push(cur->val); cur = cur->next; } while (!stacknode.empty()) { ArrayList.push_back(stacknode.top()); stacknode.pop(); } return ArrayList; } }; class {public : vector <int > printListFromTailToHead(ListNode* head) { vector <int > ArrayList; PrintListFromTailToHead(head,ArrayList); return ArrayList; } void PrintListFromTailToHead (ListNode* head,vector <int > &ArrayList) { if (head != NULL ) { if (head->next != NULL ) { PrintListFromTailToHead(head->next,ArrayList); } ArrayList.push_back(head->val); } } };
2.删除一个无头单链表的非尾节点(不能遍历链表)
1 2 3 4 5 6 7
class {public : void deleteNode (ListNode* node) { node->val = node->next->val; node->next = node->next->next; } };
3.在无头单链表的一个节点前插入一个节点(不能遍历链表)
1 2 3 4 5 6 7 8 9 10
class {public : void insertNode (ListNode* node, datatype d) { ListNode* newnode = new ListNode(node->val); newnode->next = node->next; node->next = newnode; node->val = d; } };
4.单链表实现约瑟夫环(JosephCircle)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
class Joseph {public : int getResult (int n, int m) { if (n < 0 || m < 0 ) return -1 ; int last = 0 ; for (int i=2 ;i<=n;++i){ last = (last+m)%i; } return (last+1 ); } }; class Joseph {public : int getResult (int n, int m) { std ::list <int >* JoCyList = new list <int >(); for (int i =1 ; i <= n; ++i) { JoCyList->push_back(i); } auto it = JoCyList->begin(); int count = 1 ; while (JoCyList->size() != 1 ) { if (count++ == m) { it = JoCyList->erase(it); count = 1 ; } else { it++; } if (it == JoCyList->end()) { it = JoCyList->begin(); } } return JoCyList->front(); } }; void JosephusCycxle (pList* pplist, DataType number) { assert(pplist != NULL ); assert(*pplist != NULL ); pNode tail = NULL ; pList cur = NULL ; pList kill = NULL ; int count = 0 ; if ((*pplist)->next == NULL ) { printf ("不能构成约瑟夫环n" ); return ; } cur = *pplist; while (cur->next != NULL ) { cur = cur->next; } tail = cur; tail->next = *pplist; cur = *pplist; printf ("清除顺序是:" ); while (cur != cur->next) { count = number; while (--count) { cur = cur->next; } printf ("%d-->" , cur->data); kill = cur->next; cur->data = cur->next->data; cur->next = cur->next->next; free (kill); kill = NULL ; } printf ("%dnn" , cur->data); printf ("最后一个元素是: %d nn" , cur->data); }
5.逆置/反转单链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
class Solution {public : ListNode* reverseList (ListNode* head) { if (head == NULL || head->next == NULL ) return head; ListNode* rh = reverseList(head->next); head->next->next = head; head->next = NULL ; return rh; } }; class Solution {public : ListNode* reverseList (ListNode* head) { ListNode* prev = NULL ; ListNode* cur = head; ListNode* next = NULL ; while (cur) { next = cur->next; cur->next = prev; prev = cur; cur = next; } return prev; } }; class Solution {public : ListNode* reverseList (ListNode* head) { if (head == NULL || head->next == NULL ) return head; ListNode* newhead = NULL ; while (head) { ListNode* next = head->next; head->next = newhead; newhead = head; head = next; } return newhead; } }; ListNode* reverseList (ListNode* head) { if (head == nullptr || head->next == nullptr ) return head; ListNode* dum = new ListNode(-1 ); dum -> next = head; ListNode* newhead = dum; ListNode* q = dum,*t = head,*p = head->next; while (t->next) { t -> next = p -> next; p -> next = q -> next; q -> next = p; p = t -> next; } return newhead->next; }
6.单链表排序(冒泡排序&快速排序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
class Solution {public : ListNode* sortList (ListNode* head) { ListNode* cur = NULL ; ListNode* next = NULL ; ListNode* tail = NULL ; while (head != tail) { cur = head; next = cur->next; while (next != tail) { if ((cur->val == next->val) || (cur->val < next->val)) { cur = next; next = cur->next; } else { swap(cur->val, next->val); } } tail = cur; } return head; } }; class Solution {public : ListNode* sortList (ListNode* head) { if (head==NULL ||head->next==NULL ) return head; return mergeSort(head); } ListNode* mergeSort (ListNode*head) { if (head->next==NULL ) return head; ListNode* pHead,*qHead,*pre; pHead=head; qHead=head; pre=NULL ; while (qHead!=NULL &&qHead->next!=NULL ) { qHead=qHead->next->next; pre=pHead; pHead=pHead->next; } pre->next=NULL ; ListNode *l,*r; l=mergeSort(head); r=mergeSort(pHead); return merge(l,r); } ListNode* merge (ListNode *l,ListNode*r) { ListNode *pRes=new ListNode(0 ); ListNode *temp=pRes; while (l!=NULL &&r!=NULL ) { if (l->val<=r->val) { temp->next=l; temp=temp->next; l=l->next; } else { temp->next=r; temp=temp->next; r=r->next; } } if (l!=NULL ) temp->next=l; if (r!=NULL ) temp->next=r; temp=pRes->next; delete pRes; return temp; } }; class Solution {public : void swap (int *a,int *b) { int t=*a; *a=*b; *b=t; } ListNode *partion (ListNode *pBegin,ListNode *pEnd) { if (pBegin==pEnd||pBegin->next==pEnd) return pBegin; int key=pBegin->val; ListNode *p=pBegin,*q=pBegin; while (q!=pEnd){ if (q->val<key){ p=p->next; swap(&p->val,&q->val); } q=q->next; } swap(&p->val,&pBegin->val); return p; } void quick_sort (ListNode *pBegin,ListNode *pEnd) { if (pBegin==pEnd||pBegin->next==pEnd) return ; ListNode *mid=partion(pBegin,pEnd); quick_sort(pBegin,mid); quick_sort(mid->next,pEnd); } ListNode* sortList (ListNode* head) { if (head==NULL ||head->next==NULL ) return head; quick_sort(head,NULL ); return head; } };
7.合并两个有序链表,合并后依然有序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
class Solution {public : ListNode* mergeTwoLists (ListNode* l1, ListNode* l2) { ListNode* newlist; if (l1 == l2 || l2 == NULL ) { return l1; } else if (l1 == NULL ){ return l2; } else { if (l1->val < l2->val) { newlist = l1; newlist->next = mergeTwoLists(l1->next, l2); } else { newlist = l2; newlist->next = mergeTwoLists(l1, l2->next); } } return newlist; } }; class Solution {public : ListNode* mergeTwoLists (ListNode* l1, ListNode* l2) { ListNode* newlist = NULL ; ListNode* tail = NULL ; if (l1 == l2 || l2 == NULL ) { return l1; } else if (l1 == NULL ){ return l2; } else { if (l1->val < l2->val) { newlist = l1; l1 = l1->next; } else { newlist = l2; l2 = l2->next; } tail = newlist; while (l1 != NULL && l2 != NULL ) { if (l1->val < l2->val) { tail->next = l1; l1 = l1->next; } else { tail->next = l2; l2 = l2->next; } tail = tail->next; } if (l1 == NULL ) { tail->next = l2; } else { tail->next = l1; } } return newlist; } };
8.查找单链表的中间节点,要求只能遍历一次链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
class Solution {public : ListNode* middleNode (ListNode* head) { ListNode* fast = head; ListNode* slow = head; if (head == NULL || head->next == NULL ) return head; while (fast != NULL && fast->next != NULL ) { fast = fast->next->next; slow = slow->next; } return slow; } };
9.查找单链表的倒数第k个节点,要求只能遍历一次链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
class Solution {public : ListNode* FindKthToTail (ListNode* pListHead, unsigned int k) { ListNode* fast = pListHead; ListNode* slow = pListHead; if (pListHead == nullptr ) return nullptr ; unsigned int steps = 1 ; for (;fast != nullptr ;steps++) { if (steps >k) slow = slow->next; fast = fast->next; } return steps > k? slow:nullptr ; } };
10.删除链表的倒数第K个结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
class Solution {public : ListNode* removeNthFromEnd (ListNode* head, int n) { if (!head->next) return NULL ; ListNode *pre = head, *cur = head; for (int i = 0 ; i < n; ++i) cur = cur->next; if (!cur) return head->next; while (cur->next) { cur = cur->next; pre = pre->next; } pre->next = pre->next->next; return head; } };
11.判断单链表是否带环?若带环,求环的长度?求环的入口点?并计算每个算法的时间复杂度&空间复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
class Solution {public : ListNode* EntryNodeOfLoop (ListNode* pHead) { set <ListNode*> s; ListNode* node = pHead; while (node!=NULL ){ if (s.insert(node).second) node = node->next; else return node; } return node; } }; class Solution {public : ListNode* EntryNodeOfLoop (ListNode* pHead) { ListNode *fast=pHead,*slow=pHead; while (fast && fast->next){ fast=fast->next->next; slow=slow->next; if (fast==slow) break ; } fast=pHead; if (fast==NULL || fast->next==NULL ) return NULL ; while (fast!=slow){ fast=fast->next; slow=slow->next; } return slow; } }; ListNode *IsCirle (ListNode *pHead) { if (NULL == pHead || NULL == pHead->_next) return NULL ; ListNode *fast = pHead; ListNode *slow = pHead; while (fast && fast->_next) { fast = fast->_next->_next; slow = slow->_next; if (slow == fast) return fast; } return NULL ; } ListNode *GetEnterNode (ListNode *pHead) { ListNode *pMeet = IsCirle(pHead); if (pMeet) { while (pMeet == pHead) { pHead = pHead->_next; pMeet = pMeet->_next; } } return pMeet; } int GetCirLen (ListNode *pHead) { ListNode *pMeet = IsCirle(pHead); int count = 0 ; if (pMeet) { ListNode *pNext = pMeet; while (pNext->_next != pNext) { count++; pNext = pNext->_next; } count++; } return count; }
12.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
class Solution {public : ListNode *getIntersectionNode (ListNode *headA, ListNode *headB) { if (!headA || !headB) return NULL ; int lenA = 0 , lenB = 0 ; ListNode *longNode = headA, *shortNode = headB; while (longNode) { ++lenA; longNode = longNode->next; } while (shortNode) { ++lenB; shortNode = shortNode->next; } int diff = lenA - lenB; longNode = headA; shortNode = headB; if (lenA < lenB) { diff = -diff; longNode = headB; shortNode = headA; } for (int i = 0 ; i < diff; ++i) { longNode = longNode->next; } while (longNode && shortNode && longNode != shortNode) { longNode = longNode->next; shortNode = shortNode->next; } return longNode; } }; class Solution {public : ListNode *getIntersectionNode (ListNode *headA, ListNode *headB) { ListNode *p = headA, *q = headB; while (p && q) { p = p->next; q = q->next; } while (p) { p = p->next; headA = headA->next; } while (q) { q = q->next; headB = headB->next; } while (headA && headB && headA != headB) { headA = headA->next; headB = headB->next; } return headA; } };
13.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
Node* IsCircle (Node* head) { if (head == NULL ) { return NULL ; } Node* pSlow = head; Node* pFast = head; while (pFast && pFast->_next) { pFast = pFast->_next->_next; pSlow = pSlow->_next; if (pFast == pSlow) { break ; } if (pFast && pFast->_next) { return pFast; } return NULL ; } Node* GetEntryNode (Node* head, Node* meetNode) { assert(head && meetNode); Node* p1 = head; Node* p2 = meetNode; while (p1 != p2) { p1 = p1->_next; p2 = p2->_next; } return p1; } Node* IsMeet (Node* head1,Node* head2) { assert(head1 && head2); Node* cur1 = head1; int count1 = 0 ; Node* cur2 = head2; int count2 = 0 ; while (cur1->_next) { ++count1; cur1 = cur1->_next; } while (cur2->_next) { count2++; cur2 = cur2->_next; } if (cur1 != cur2) { return NULL ; } int D_val = count2 - count1; if (D_val < 0 ) { D_val = -D_val; } cur1 = head1; cur2 = head2; if (count1 < count2) { while (cur2 && D_val--) { cur2 = cur2->_next; } while (cur2 && cur1 != cur2) { cur1 = cur1->_next; cur2 = cur2->_next; } if (cur1 == cur2) { return cur1; } } else { while (cur1 && D_val--) { cur1 = cur1->_next; } while (cur1 && cur1 != cur2) { cur1 = cur1->_next; cur2 = cur2->_next; } if (cur1 == cur2) { return cur1; } } return NULL ; } Node* IsHaveCrossNode (Node* head1,Node* head2) { assert(head1); assert(head2); Node* meetNode1 = IsCircle(head1); Node* meetNode2 = IsCircle(head2); if (meetNode1 == NULL || meetNode2 == NULL ) { return NULL ; } Node* cur1 = meetNode1->_next; while (cur1 != meetNode1 && cur1 != meetNode2) { cur1 = cur1->_next; } if (cur1 != meetNode2) { return NULL ; } Node* entry1 = GetEntryNode(head1, meetNode1); Node* entry2 = GetEntryNode(head2, meetNode2); if (entry1 == entry2) { entry1->_next = NULL ; entry2->_next = NULL ; Node* meet = IsMeet(head1, head2); return meet; } return entry1; }
14.复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
class Solution {public : RandomListNode* Clone (RandomListNode* pHead) { if (!pHead) return NULL ; RandomListNode* currNode ; currNode = pHead; while (currNode ){ RandomListNode *node = new RandomListNode(currNode->label); node->next = currNode->next; currNode->next = node; currNode = node->next; } currNode = pHead; while (currNode){ RandomListNode *node = currNode->next; if (currNode->random){ node->random = currNode->random->next; } currNode = node->next; } RandomListNode *pCloneHead = pHead->next; RandomListNode *tmp; currNode = pHead; while (currNode->next){ tmp = currNode->next; currNode->next =tmp->next; currNode = tmp; } return pCloneHead; } };
15.求两个已排序单链表中相同的数据。void UnionSet(Node l1, Node l2);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
void UnionSet (Node* l1, Node* l2) { assert(l1 && l2); while (l1 && l2){ if (l1->_data < l2->_data){ l1 = l1->_next; } else if (l1->_data > l2->_data){ l2 = l2->_next; } else { printf ("%d " ,l1->_data); l1 = l1->_next; l2 = l2->_next; } } }
16.比较顺序表和链表的优缺点,他们分别在什么场景下使用它?
2.使用两个栈实现一个队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
class MyQueue {public : MyQueue() { } void push (int x) { stack1.push(x); } int pop () { if (stack2.empty()) { while (!stack1.empty()) { stack2.push(stack1.top()); stack1.pop(); } } int res = stack2.top(); stack2.pop(); return res; } int peek () { if (stack2.empty()) { while (!stack1.empty()) { stack2.push(stack1.top()); stack1.pop(); } } return stack2.top(); } bool empty () { return stack2.empty() && stack1.empty(); } private : stack <int > stack1; stack <int > stack2; };
3.使用两个队列实现一个栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
class MyStack {public : MyStack() { } void push (int x) { que1.push(x); } int pop () { while (que1.size() > 1 ) { que2.push(que1.front()); que1.pop(); } int front = que1.front(); que1.pop(); while (!que2.empty()) { que1.push(que2.front()); que2.pop(); } return front; } int top () { return que1.back(); } bool empty () { return que1.empty(); } private : queue <int > que1; queue <int > que2; };
4.元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
class Solution {public : bool IsPopOrder (vector <int > pushV,vector <int > popV) { std ::stack <int > st; int index = 0 ; int outdex = 0 ; while (index < pushV.size()) { if (st.empty() || st.top() != popV[outdex]) { st.push(pushV[index]); ++index; } else { st.pop(); ++outdex; } } while (!st.empty()) { if (st.top() != popV[outdex++]) { return false ; } st.pop(); } return true ; } };
5.一个数组实现两个栈(共享栈)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
typedef struct ShareStack { Datatype a[N]; int top1; int top2; }SharkStack, *pShareStack; void ShareStackInit (pShareStack pss) { assert(pss); pss->top1 = -2 ; pss->top2 = -1 ; } void ShareStackPush (pShareStack pss, Datatype x, int which) { assert(pss); if (which == 1 ) { if (pss->top1 >= N) { printf ("Stack Overflownn" ); return ; } pss->top1 += 2 ; pss->a[pss->top1] = x; } else if (which == 2 ) { if (pss->top2 >= N) { printf ("Stack Overflownn" ); return ; } pss->top2 += 2 ; pss->a[pss->top2] = x; } else { assert(false ); } } void ShareStackPop (pShareStack pss, int which) { assert(pss); if (which == 1 ) { if (pss->top1 < -2 ) { printf ("Stack NULLnn" ); return ; } pss->top1 -= 2 ; } else { if (pss->top2 < -1 ) { printf ("Stack NULLnn" ); return ; } pss->top2 -= 2 ; } } Datatype ShareStackTop (pShareStack pss, int which) { assert(pss); if (which == 1 ) { return pss->a[pss->top1]; } else { return pss->a[pss->top2]; } } void test () { SharkStack pss; ShareStackInit(&pss); ShareStackPush(&pss, 1 , 1 ); ShareStackPush(&pss, 2 , 2 ); ShareStackPush(&pss, 3 , 1 ); ShareStackPush(&pss, 4 , 2 ); ShareStackPush(&pss, 5 , 1 ); ShareStackPush(&pss, 6 , 2 ); ShareStackPush(&pss, 7 , 1 ); ShareStackPush(&pss, 8 , 2 ); printf ("栈一:" ); while (pss.top1 >= 0 ) { printf (" %d " , ShareStackTop(&pss, 1 )); ShareStackPop(&pss, 1 ); } printf ("nn" ); printf ("栈二:" ); while (pss.top2 >= 1 ) { printf (" %d " , ShareStackTop(&pss, 2 )); ShareStackPop(&pss, 2 ); } printf ("nn" ); }
近期评论