【資料結構】連結串列面試題升級版
阿新 • • 發佈:2018-12-28
1、複雜連結串列的複製
複雜連結串列
一個連結串列的每個結點,有一個next指標指向下一個結點,還有一個random指標指向這個連結串列中的隨機一個結點或者NULL。
現在要求複製這個連結串列,並返回複製後的新連結串列。
思路如下:
複雜連結串列的資料型別:
typedef struct ComplexNode
{
int data;
ComplexNode *next;
ComplexNode *random;
}ComplexNode;
程式碼如下:
//建立一個新結點 ComplexNode *CreateComNode(int data) { ComplexNode *newNode = (ComplexNode *)malloc(sizeof(ComplexNode)); newNode->data = data; newNode->next = NULL; newNode->random = NULL; return newNode; } ComplexNode *CopyComplexList(ComplexNode **pFirst) { ComplexNode *newNode = NULL; ComplexNode *cur = NULL; //1.複製每個結點,讓新結點跟在老結點後面 cur = *pFirst; while(cur != NULL) { newNode = CreateComNode(cur->data); newNode->next = cur->next; cur->next = newNode; cur = newNode->next; } //2、複製random cur = *pFirst; while(cur != NULL) { newNode = cur->next; if(cur->random != NULL) { newNode->random = cur->random->next; } cur = newNode->next; } //3、把一個連結串列拆成兩個連結串列 ComplexNode *newNext = NULL; ComplexNode *next = NULL; ComplexNode *result = NULL; int flag = 1; cur = *pFirst; while(cur != NULL) { newNode = cur->next; if(flag) { result = newNode; flag = 0; } next = newNode->next; if(next == NULL) { newNext = NULL; } else { newNext = next->next; } cur->next = next; newNode->next = newNext; cur = next; } return result; }
2、判斷兩個連結串列是否相交,若相交,求交點(假設連結串列不帶環)
思路如下:
程式碼如下:
//計算連結串列長度 int GetListLen(ListNode *p) { int count = 0; ListNode *cur = p; while(cur != NULL) { count++; cur = cur->next; } return count; } //判斷兩條連結串列是否相交,若相交,返回交點 ListNode *IsIntersect(ListNode *p1, ListNode *p2) { ListNode *cur1 = p1; ListNode *cur2 = p2; int len1 = 0; int len2 = 0; int ret = 0; while(cur1 != NULL) { cur1 = cur1->next; } while(cur2 = cur2->next) { cur2 = cur2->next; } if(cur1 == cur2)//如果條件成立,說明相交 { cur1 = p1; cur2 = p2; len1 = GetListLen(p1); len2 = GetListLen(p2); if(len1>len2) { ret = len1-len2; while(ret--) { cur1 = cur1->next; } } else if(len1<len2) { ret = len2-len1; while(ret--) { cur2 = cur2->next; } } while(cur1 != cur2) { cur1 = cur1->next; cur2 = cur2->next; } return cur1; //找到交點 } else return NULL; }
3、判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點?
思路如下:
程式碼如下:
//判斷是否帶環,帶環返回快慢指標相遇結點 ListNode *IsCircleList(ListNode *p) { int count = 0; ListNode *fast = p; ListNode *slow = p; while(fast != NULL) { fast = fast->next; count++; if(count%2==0) { slow = slow->next; } if(fast == NULL) { break; } if(fast == slow) { return fast; } } return NULL; } //求環的長度 int LenOfCircle(ListNode *p) { int count = 0; ListNode *cur = NULL; ListNode *NodeInCircle = NULL; //從頭遍歷連結串列,找到相遇點 NodeInCircle = IsCircleList(p); cur = p; while(cur != NodeInCircle) { cur = cur->next; } while(cur->next != NodeInCircle) { cur = cur->next; count++; } count++; return count; } //求環的入口點 ListNode *EntryNode(ListNode *p) { ListNode *dot = NULL; ListNode *ret = NULL; ListNode *cur = NULL; ListNode *NodeInCircle = NULL; //從頭遍歷連結串列,找到相遇點 NodeInCircle = IsCircleList(p); cur = p; //找出相遇點的前一個結點,將它置為空指標,相當於從相遇點斷開環 //然後以兩條連結串列相交的角度找入口點,兩條連結串列相交處就是環的入口點 while(cur->next != NodeInCircle) { cur = cur->next; } dot = cur; cur->next = NULL; cur = NodeInCircle; ret = p; while(cur != ret) { cur = cur->next; ret = ret->next; } dot->next = NodeInCircle; return cur; }
4、判斷兩個連結串列是否相交,若相交,求交點(假設連結串列帶環)【升級版】
思路如下: