單鏈表及相關面試題
阿新 • • 發佈:2019-01-02
//SlistNode.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <assert.h>
typedef int Datatype;
typedef struct SlistNode
{
Datatype data;
struct SlistNode* next;
}SlistNode;
void InitSlist(SlistNode*& pHead);
void PrintList(SlistNode*& pHead);
void PushBack(SlistNode*& pHead,Datatype a);
void PopBack(SlistNode*& pHead);
void PushFront(SlistNode*& pHead, Datatype a);
void PopFront(SlistNode*& pHead);
void Insert(SlistNode*& pHead, SlistNode*& pos, Datatype a);
void Erase(SlistNode*& pHead, SlistNode*& pos);
void Remove(SlistNode*& pHead,Datatype a);
SlistNode* Find(SlistNode* pHead, Datatype a);
void Destory(SlistNode*& pHead);
SlistNode* BuyNode(Datatype a);
/////////單鏈表有關面試題////////////
void PrintListFromT2H(SlistNode* pHead);
void ReverseList(SlistNode*& pHead);//逆置/反轉單鏈表
//刪除一個無頭單鏈表的非尾節點
void DeleteNotpHead(SlistNode* pos);
//在無頭單鏈表的一個非頭節點前插入一個節點
void InsertNotpHead(SlistNode* pos, Datatype a);
//單鏈表實現約瑟夫環
SlistNode* JosephCircle(SlistNode* pHead, int k);
//氣泡排序
void BubbleSort(SlistNode* pHead);
//合併兩個有序連結串列合併後依然有序
SlistNode* Merge(SlistNode* pHead1, SlistNode* pHead2);
//查詢單鏈表的中間節點,要求只遍歷一次連結串列
SlistNode* FindMiddleNode(SlistNode* pHead);
//查詢單鏈表中倒數第k個節點,要求只遍歷一次
SlistNode* FindNode(SlistNode* pHead,int k);
//判斷單鏈表是否帶環,若帶環,求環的長度
SlistNode* IsCircle(SlistNode* pHead);
size_t CircleLength(SlistNode* pHead);
//求環的入口點
SlistNode* CircleEntry(SlistNode* pHead);
//判斷兩個連結串列是否相交,求交點
SlistNode* GetMeetNode(SlistNode* pHead1, SlistNode* pHead2);
//求兩個已排序單鏈表中的相同資料
void UnionSet(SlistNode* list1, SlistNode* list2);
//SlistNode.c
#include "SlistNode.h"
void InitSlist(SlistNode*& pHead)
{
pHead = NULL;
}
void PrintList(SlistNode*& pHead)
{
SlistNode* temp = pHead;
if (temp == NULL)
{
return;
}
while (temp)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
SlistNode* BuyNode(Datatype a)
{
SlistNode* node = (SlistNode*)malloc(sizeof(SlistNode));
assert(node);
node->data = a;
node->next = NULL;
return node;
}
void PushBack(SlistNode*& pHead, Datatype a)
{
if (pHead == NULL)
{
pHead = BuyNode(a);
}
else
{
SlistNode* pcur = pHead;
while (pcur->next)
{
pcur = pcur->next;
}
pcur->next = BuyNode(a);
}
}
void PopBack(SlistNode*& pHead)
{
assert(pHead);
if (pHead->next == NULL)
{
free(pHead);
pHead = NULL;
}
else
{
SlistNode* pcur = pHead;
SlistNode* pre = pcur;
while (pcur->next)
{
pre = pcur;
pcur = pcur->next;
}
free(pcur);
pcur = NULL;
pre->next = NULL;
}
}
void PushFront(SlistNode*& pHead, Datatype a)
{
assert(pHead);
if (pHead == NULL)
{
pHead = BuyNode(a);
}
else
{
SlistNode* newnode = BuyNode(a);
newnode->next = pHead;
pHead = newnode;
}
}
void PopFront(SlistNode*& pHead)
{
assert(pHead);
if (pHead == NULL)
{
return;
}
else if (pHead->next==NULL)
{
free(pHead);
pHead = NULL;
}
else
{
SlistNode* pcur = pHead;
pHead = pHead->next;
free(pcur);
pcur = NULL;
}
}
void Insert(SlistNode*& pHead, SlistNode*& pos, Datatype a)//在pos之前插入資料
{
assert(pHead);
assert(pos);
if (pHead == pos)
{
SlistNode* newnode = BuyNode(a);
newnode->next = pHead;
pHead = newnode;
}
else
{
SlistNode* pcur = pHead;
SlistNode* pre = pcur;
while (pcur != pos)
{
pre = pcur;
pcur = pcur->next;
}
SlistNode* newnode = BuyNode(a);
newnode->next = pcur;
pre->next = newnode;
}
}
SlistNode* Find(SlistNode* pHead, Datatype a)
{
assert(pHead);
SlistNode* temp = pHead;
while (temp)
{
if (temp->data == a)
{
return temp;
}
temp = temp->next;
}
return NULL;
}
void Erase(SlistNode*& pHead, SlistNode*& pos)
{
assert(pHead&&pos);
if (pos == pHead)
{
SlistNode* temp = pHead;
pHead = pHead->next;
free(temp);
temp = NULL;
}
else
{
SlistNode* pcur = pHead;
while (pcur->next != pos)
{
pcur = pcur->next;
}
pcur->next = pos->next;
free(pos);
pos = NULL;
}
}
void Remove(SlistNode*& pHead, Datatype a)
{
assert(pHead);
SlistNode* pos = Find(pHead, a);
if (pos == pHead)
{
SlistNode* temp = pHead;
pHead = pHead->next;
free(temp);
temp = NULL;
}
else
{
SlistNode* pcur = pHead;
while (pcur->next != pos)
{
pcur = pcur->next;
}
pcur->next = pos->next;
free(pos);
pos = NULL;
}
}
void Destory(SlistNode*& pHead)
{
assert(pHead);
free(pHead);
pHead = NULL;
}
void PrintListFromT2H(SlistNode* pHead)//從尾到頭列印
{
if (pHead)
{
PrintListFromT2H(pHead->next);
printf("%d ", pHead->data);
}
}
void ReverseList(SlistNode*& pHead)//逆置/反轉單鏈表
{
assert(pHead);
SlistNode* newhead = NULL;
SlistNode* pcur = pHead;
while (pcur)
{
SlistNode*temp = pcur;//摘節點
pcur = pcur->next;
temp->next = newhead;//頭插
newhead = temp;
}
pHead = newhead;
}
void DeleteNotpHead(SlistNode*pos)
{
assert(pos);
SlistNode* next = pos->next;
pos->data = next->data;
pos->next = next->next;
free(next);
}
void InsertNotpHead(SlistNode* pos, Datatype a)
{
assert(pos);
SlistNode* newnode = BuyNode(pos->data);
SlistNode* next = pos->next;
pos->next = newnode;
newnode->next = next;
pos->data = a;
}
SlistNode* JosephCircle(SlistNode* pHead, int k)
{
SlistNode* pcur = pHead;
while (pcur->next != pcur)
{
int x = k;
while (--x)
{
pcur = pcur->next;
}
SlistNode* next = pcur->next;
pcur->data = next->data;
pcur->next = next->next;
free(next);
}
return pcur;
}
void BubbleSort(SlistNode* pHead)
{
if (pHead == NULL&&pHead->next == NULL)
{
return;
}
else
{
SlistNode* tail = NULL;
int flag = 1;
while (tail != pHead->next)
{
SlistNode* pcur = pHead;
SlistNode* pnext = pcur->next;
do
{
if (pcur->data > pnext->data)
{
Datatype ret = pcur->data;
pcur->data = pnext->data;
pnext->data = ret;
flag = 0;
}
pcur = pcur->next;
pnext = pnext->next;
}while (pnext!= tail);
if (flag == 1)
{
return;
}
tail = pcur;
}
}
}
SlistNode* Merge(SlistNode* pHead1, SlistNode* pHead2)
{
if (pHead1==NULL)
{
return pHead2;
}
else if (pHead2==NULL)
{
return pHead1;
}
else
{
SlistNode* newhead ,*tail;
SlistNode* l1 = pHead1;
SlistNode* l2 = pHead2;
if (l1->data > l2->data)
{
newhead = tail = l2;
}
else
{
newhead = tail = l1;
}
while (l1!=NULL && l2!=NULL)
{
SlistNode* temp ;
if (l1->data < l2->data)
{
temp = l1;
l1 = l1->next;
}
else
{
temp = l2;
l2 = l2->next;
}
tail->next = temp;
tail=temp;
}
if (l2)
{
tail->next = l2;
}
if (l1)
{
tail->next = l1;
}
return newhead;
}
}
SlistNode* FindMiddleNode(SlistNode* pHead)
{
assert(pHead);
SlistNode* fast = pHead;
SlistNode* slow = pHead;
while (fast&&fast->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
SlistNode* FindNode(SlistNode* pHead,int k)
{
assert(pHead);
SlistNode* fast = pHead;
SlistNode* slow = pHead;
while (k--)
{
fast = fast->next;
}
while (fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
SlistNode*IsCircle(SlistNode* pHead)
{
assert(pHead);
SlistNode* fast = pHead;
SlistNode* slow = pHead;
while (fast &&fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
return slow;
}
}
return NULL;
}
size_t CircleLength(SlistNode* pHead)
{
assert(pHead);
int count = 1;
SlistNode* meet = IsCircle(pHead);
SlistNode* pcur = meet->next;
while (pcur != meet)
{
pcur = pcur->next;
count++;
}
return count;
}
SlistNode* CircleEntry(SlistNode* pHead)
{
assert(pHead);
SlistNode* meet = IsCircle(pHead);
SlistNode* pcur = pHead;
while (pcur != meet)
{
pcur = pcur->next;
meet = meet->next;
}
return pcur;
}
SlistNode* GetMeetNode(SlistNode* pHead1, SlistNode* pHead2)//不帶環
{
assert(pHead1);
assert(pHead2);
SlistNode* pcur1 = pHead1;
SlistNode* pcur2 = pHead2;
int len1 = 0;
int len2 = 0;
while (pcur1)
{
pcur1 = pcur1->next;
len1++;
}
while (pcur2)
{
pcur2 = pcur2->next;
len2++;
}
int k = abs(pcur1 - pcur2);
SlistNode* longlist,*shortlist;
if (len1 > len2)
{
longlist = pHead1;
shortlist = pHead2;
}
else
{
longlist = pHead2;
shortlist = pHead1;
}
while (k--)
{
longlist = longlist->next;
}
while (longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
return shortlist;
}
void UnionSet(SlistNode* list1, SlistNode* list2)
{
assert(list1);
assert(list2);
while (list1&&list2)
{
if (list1->data > list2->data)
{
list2 = list2->next;
}
else if (list1->data < list2->data)
{
list1 = list1->next;
}
else
{
printf("%d ", list1->data);
list1 = list1->next;
list2 = list2->next;
}
}
printf("\n");
}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SlistNode.h"
void test1()
{
SlistNode* Node;
InitSlist(Node);
PushBack(Node, 1);
PushBack(Node, 2);
PushBack(Node, 3);
//PrintList(Node);
//PopBack(Node);
//PopBack(Node);
//PushFront(Node, 4);
//PushFront(Node, 5);
//PrintList(Node);
//PopFront(Node);
//PopFront(Node);
// PrintList(Node);
//SlistNode* pos1 = Find(Node, 4);
//Insert(Node, pos1, 0);//在pos之前插入資料
//PrintList(Node);
//SlistNode* pos2 = Find(Node, 5);
// Erase(Node, pos2);
//Remove(Node, 1);
//ReverseList(Node);//逆置/反轉單鏈表
// PrintList(Node);
//PrintListFromT2H(Node);//從尾到頭列印
//printf("\n");
//Destory(Node);
}
void test2()
{
SlistNode* Node;
InitSlist(Node);
PushBack(Node, 1);
PushBack(Node, 2);
PushBack(Node, 3);
PushBack(Node, 7);
PushBack(Node, 5);
PrintList(Node);
//Remove(Node, 1);
SlistNode* pos = Find(Node, 5);
//InsertNotpHead(pos, 0);
pos->next = Node;
SlistNode* ret = JosephCircle(Node, 3);
printf("%d\n", ret->data);
//PrintList(Node);
/*SlistNode* pos = Find(Node, 1);
DeleteNotpHead(pos);
PrintList(Node);*/
}
void test3()
{
SlistNode* Node1;
InitSlist(Node1);
PushBack(Node1, 1);
PushBack(Node1, 3);
PushBack(Node1, 4);
PushBack(Node1, 5);
PushBack(Node1, 7);
PushBack(Node1, 8);
PrintList(Node1);
//SlistNode* ret = FindMiddleNode(Node1);
SlistNode* ret = FindNode(Node1, 1);
printf("%d\n", ret->data);
//SlistNode* Node2;
//InitSlist(Node2);
//PushBack(Node2, 2);
//PushBack(Node2, 4);
//PushBack(Node2, 6);
//PushBack(Node2, 8);
//PushBack(Node2, 8);
//PrintList(Node2);
//SlistNode* Node=Merge(Node1, Node2);
////BubbleSort(Node);
//PrintList(Node);
}
void test4()
{
SlistNode* Node1;
InitSlist(Node1);
PushBack(Node1, 1);
PushBack(Node1, 3);
PushBack(Node1, 4);
PushBack(Node1, 6);
PushBack(Node1, 7);
PrintList(Node1);
SlistNode* Node2;
InitSlist(Node2);
PushBack(Node2, 1);
PushBack(Node2, 4);
PushBack(Node2, 6);
PushBack(Node2, 8);
PushBack(Node2, 9);
PrintList(Node2);
UnionSet(Node1, Node2);
/*SlistNode* ret = Find(Node1, 4);
SlistNode* tail = Find(Node1, 7);
tail->next = ret;
SlistNode*meet= GetMeetNode(Node1,Node2);
printf("%d", meet->data);*/
//SlistNode* ret = Find(Node1, 3);
//SlistNode* tail = Find(Node1, 7);
//tail->next = ret;
//SlistNode* pos = IsCircle(Node1);
//printf("%d\n", pos->data);
//size_t length = CircleLength(Node1);
//printf("%u\n", length);
//SlistNode* entry = CircleEntry(Node1);
//printf("%d\n", entry->data);
}
int main()
{
//test1();
//test2();
//test3();
test4();
system("pause");
return 0;
}