資料結構之單向連結串列(C++語言描述)
阿新 • • 發佈:2019-02-02
該檔案是整個原始檔,包括單向連結串列節點的定義,各種操作函式,main()測試用例。
#include <iostream>
using namespace std;
struct ListNode //用class時需要加public,因為public預設是private的
{
int m_nValue;
ListNode* m_pNext;
};
ListNode* CreateList();//新建單向連結串列
void deleteListMemory(ListNode** pHead);//刪除連結串列記憶體
void PrintListNode(ListNode* pHead);//列印單向連結串列
int ListLength(ListNode* pHead);//單向連結串列測長
ListNode* SearchListNode1(ListNode* pHead, int pos);//查詢第pos位置的節點
int SearchListNode2(ListNode* pHead, int value);//查詢值為value的節點所在的位置
ListNode* InsertListNode(ListNode** pHead, int pos, int data);//在第pos個節點的後面插入新節點,
//當pos等於0時,表示在頭結點前面插入新節點
ListNode* DeleteListNode1(ListNode** pHead, int pos);//指定刪除第pos位置的節點,pos從1開始
ListNode* DeleteListNode2(ListNode** pHead, int value);//刪除資料為value的所有節點
ListNode* ReverseList(ListNode* pHead);//翻轉一個連結串列
ListNode* SearchMidNode(ListNode* pHead);//尋找中間節點
ListNode* InsertNodeOrderly(ListNode* pHead);//在從小到大的排序連結串列pHead中插入節點,節點數值從控制檯輸入
ListNode* InsertNodeOrderly(ListNode* pHead, ListNode* pInsertNode);//將節點從引數傳入,並插入
bool HasLoopInList(ListNode* pHead,ListNode** start);//判斷是否有迴環,如果有,將環的開始節點儲存在start中
ListNode* MergeListsOrderly(ListNode* pHead1, ListNode* pHead2);//合併有序單鏈表,非遞迴方法
ListNode* MergeListsOrderly_Recursively(ListNode* pHead1, ListNode* pHead2);//合併有序單鏈表,遞迴方法
int LastRemaining_Josephuse(unsigned int num, unsigned int kth);//約瑟夫環問題
ListNode* CreateLoopList();//新建單向迴圈連結串列,用於約瑟夫環
void PrintListFromTail_Iteratively(ListNode* pHead);//從尾部到頭列印連結串列,非遞迴,迭代
void PrintListFromTail_Recursively(ListNode* pHead);//從尾部到頭列印連結串列,遞迴
int main()
{
ListNode* pHead = CreateList();
cout << endl;
//PrintListNode(pHead);
//cout << endl;
//int length = ListLength(pHead);
//if (length != 0) cout << length << endl;
//ListNode* result1 = SearchListNode1(pHead, 3);
//if (result1 != NULL) cout << result1->m_nValue << endl;
//int position = SearchListNode2(pHead, 7);
//if (position) cout << position << endl;
//ListNode* pNode = NULL;
//ListNode* result2 = InsertListNode(&pHead, 3, 4);
//if (result2 != NULL) PrintListNode(result2);
//cout << endl;
//ListNode* result3 = DeleteListNode1(&pHead, 3);
//if (result3 != NULL) PrintListNode(result3);
//ListNode* result4 = DeleteListNode2(&pHead, 3);
//if (result4 != NULL) PrintListNode(result4);
//ListNode* result5 = ReverseList(pHead);
//if (result5 != NULL) PrintListNode(result5);
//ListNode* result6 = SearchMidNode(pHead);
//if (result6 != NULL) cout << result6->m_nValue << endl;
//ListNode* pHead1 = new ListNode();ListNode* node1 = new ListNode();ListNode* node2 = new ListNode();
//ListNode* node3 = new ListNode();ListNode* node4 = new ListNode();ListNode* node5 = new ListNode();
//pHead1->m_nValue = 1;pHead1->m_pNext = node1;node1->m_nValue = 3;node1->m_pNext = node2;
//node2->m_nValue = 4;node2->m_pNext = node3;node3->m_nValue = 6;node3->m_pNext = node4;
//node4->m_nValue = 7;node4->m_pNext = node5;node5->m_nValue = 9;node5->m_pNext = NULL;
//ListNode* result7 = InsertNodeOrderly(pHead);
//if (result7 != NULL) PrintListNode(result7);
//delete pHead, node1, node2, node3, node4, node5;
//pHead = node1 = node2 = node3 = node4 = node5 = NULL;
//ListNode* start = NULL;
//bool result8 = HasLoopInList(pHead, &start);
//if (start != NULL || result8) cout << start->m_nValue << endl;
//ListNode* pHead2 = CreateList();
//cout << endl;
//ListNode* result9 = NULL;
//result9 = MergeListsOrderly(pHead1, pHead2);
//if (result9 != NULL) PrintListNode(result9);
//ListNode* pHead2 = CreateList();
//cout << endl;
//ListNode* result10 = NULL;
//result10 = MergeListsOrderly_Recursively(pHead1, pHead2);
//if (result10 != NULL) PrintListNode(result10);
//int result11 = -1;
//result11 = LastRemaining_Josephuse(3, 0);
//if (result11 != -1) cout << result11 << endl;
//ListNode* pHead = CreateLoopList();
//if (pHead != NULL) PrintListNode(pHead);
//PrintListFromTail_Iteratively(pHead);
//cout << endl;
//PrintListFromTail_Recursively(pHead);
//cout << endl;
deleteListMemory(&pHead);
system("pause");
return 0;
}
ListNode* CreateList()
{
ListNode* pHead = NULL;
ListNode* pNode = NULL;
ListNode* pLastNode = NULL;
int inputValue = 0;
while (cin >> inputValue)
{
pNode = new ListNode();
if (pNode == NULL)
{
cout << "申請記憶體失敗!" << endl;
return NULL;
}
pNode->m_nValue = inputValue;
pNode->m_pNext = NULL;
if (pHead == NULL)
{
pHead = pNode;
}
else
{
pLastNode->m_pNext = pNode;
}
pLastNode = pNode;
}
return pHead;
}
void deleteListMemory(ListNode** pHead)
{
if (*pHead == NULL || pHead == NULL) return;
ListNode* pNode = *pHead;
ListNode* pDeleted = NULL;
while (pNode != NULL)
{
pDeleted = pNode;
pNode = pNode->m_pNext;
delete pDeleted;
pDeleted = NULL;
}
pHead = NULL;
}
void PrintListNode(ListNode* pHead)
{
if (NULL == pHead)
{
cout << "The list is empty!" << endl;
return;
}
ListNode* pNode = pHead;
while (pNode != NULL)
{
cout << pNode->m_nValue << " ";
pNode = pNode->m_pNext;
}
return;
}
int ListLength(ListNode* pHead)
{
if (NULL == pHead)
{
cout << "The list is empty!" << endl;
return 0;
}
int length = 0;
ListNode* pNode = pHead;
while (pNode != NULL)
{
++length;
pNode = pNode->m_pNext;
}
return length;
}
ListNode* SearchListNode1(ListNode* pHead, int pos)
{
if (pHead == NULL || pos <= 0)
{
cout << "Error:invalid input!" << endl;
return NULL;
}
if (1 == pos) return pHead;
else
{
ListNode* pNode = pHead;
int index = 2;
while (index <= pos)
{
pNode = pNode->m_pNext;
if (NULL == pNode)
{
cout << "Error:the pos is larger than the length!" << endl;
return NULL;
}
++index;
}
return pNode;
}
}
int SearchListNode2(ListNode* pHead, int value)
{
if (NULL == pHead)
{
cout << "Error:the list is empty!" << endl;
return 0;
}
ListNode* pNode = pHead;
int pos = 1;
while (pNode != NULL && pNode -> m_nValue != value)
{
pos++;
pNode = pNode->m_pNext;
}
if (NULL == pNode)
{
cout << "Can't find the node!" << endl;
return 0;
}
else return pos;
}
ListNode* InsertListNode(ListNode** pHead, int pos, int data)
{
if (pos < 0)
{
cout << "Error:the position is invalid!" << endl;
}
ListNode* pNew = new ListNode();
pNew->m_nValue = data;
pNew->m_pNext = NULL;
if (NULL == pHead || NULL == *pHead)
{
*pHead = pNew;
}
else if (0 == pos)
{
pNew->m_pNext = *pHead;
*pHead = pNew;
}
else
{
ListNode* pNode = SearchListNode1(*pHead, pos);
if (pNode != NULL)
{
pNew->m_pNext = pNode->m_pNext;
pNode->m_pNext = pNew;
}
}
return *pHead;
}
ListNode* DeleteListNode1(ListNode** pHead, int pos)
{
if (*pHead == NULL || pHead == NULL || pos <= 0)
{
cout << "List is empty or the position is invalid!" << endl;
return *pHead;
}
if (pos == 1)
{
ListNode* pDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
delete pDeleted;
pDeleted = NULL;
return *pHead;
}
else
{
ListNode* pNode = SearchListNode1(*pHead, pos - 1);
if (pNode != NULL && pNode->m_pNext != NULL)
{
ListNode* pDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
delete pDeleted;
pDeleted = NULL;
}
return *pHead;
}
}
ListNode* DeleteListNode2(ListNode** pHead, int value)
{
if (*pHead == NULL || pHead == NULL)
{
cout << "List is empty!" << endl;
return NULL;
}
ListNode* pToBeDeleted = NULL;
while ((*pHead) != NULL && (*pHead)->m_nValue == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
ListNode* pNode = *pHead;
while (pNode != NULL && pNode->m_pNext != NULL)
{
while (pNode->m_pNext->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
{
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
if (pNode->m_pNext->m_nValue != value)
{
pNode = pNode->m_pNext;
}
else//pNode->m_pNext->m_pNext == NULL
{
if (pNode->m_pNext->m_nValue == value)
{
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
}
return *pHead;
}
ListNode* ReverseList(ListNode* pHead)
{
if (pHead == NULL)
{
cout << "List is empty!" << endl;
return NULL;
}
if (pHead->m_pNext == NULL) return pHead;
ListNode* pPreNode = pHead;
ListNode* pCurNode = pHead->m_pNext;
ListNode* pNxtNode = pCurNode->m_pNext;
ListNode* pReverseHead = NULL;
pPreNode->m_pNext = NULL;
while (pNxtNode != NULL)
{
pCurNode->m_pNext = pPreNode;
pPreNode = pCurNode;
pCurNode = pNxtNode;
pNxtNode = pCurNode->m_pNext;
}
pCurNode->m_pNext = pPreNode;
pReverseHead = pCurNode;
return pReverseHead;
}
ListNode* SearchMidNode(ListNode* pHead)
{
if (NULL == pHead)
{
cout << "List is empty!" << endl;
return NULL;
}
ListNode* pCurNode = pHead;
ListNode* pMidNode = pHead;
int curIndex = 0;
int midIndex = 0;
while (pCurNode != NULL)
{
if (curIndex / 2 > midIndex)
{
midIndex++;
pMidNode = pMidNode->m_pNext;
}
curIndex++;
pCurNode = pCurNode->m_pNext;
}
return pMidNode;
}
ListNode* InsertNodeOrderly(ListNode* pHead)
{
int value = 0;
while (cin >> value)
{
ListNode* pInsertNode = new ListNode();
pInsertNode->m_nValue = value;
pInsertNode->m_pNext = NULL;
if (pHead == NULL)
{
pHead = pInsertNode;
continue;
}
if (pInsertNode->m_nValue <= pHead->m_nValue)
{
pInsertNode->m_pNext = pHead;
pHead = pInsertNode;
continue;
}
ListNode* pCurNode = pHead;
ListNode* pPreNode = NULL;
while (pInsertNode->m_nValue > pCurNode->m_nValue && pCurNode->m_pNext != NULL)
{
pPreNode = pCurNode;
pCurNode = pCurNode->m_pNext;
}
if (pInsertNode->m_nValue <= pCurNode->m_nValue)
{
pPreNode->m_pNext = pInsertNode;
pInsertNode->m_pNext = pCurNode;
}
else pCurNode->m_pNext = pInsertNode;
}
return pHead;
}
bool HasLoopInList(ListNode* pHead, ListNode** start)
{
if (pHead == NULL)
{
cout << "List is empty!" << endl;
*start = NULL;
return false;
}
ListNode* pBehind = pHead;
ListNode* pAhead = pHead->m_pNext;
if (pAhead == NULL)
{
cout << "List has only one node, has no loop!" << endl;
*start = NULL;
return false;
}
while (pAhead != NULL && pBehind != NULL)
{
if (pAhead == pBehind)
{
int nodesInLoop = 1;
ListNode* pNode1 = pAhead;
while (pNode1->m_pNext != pAhead)
{
++nodesInLoop;
pNode1 = pNode1->m_pNext;
}
pNode1 = pHead;
for (int i = 0; i < nodesInLoop; ++i)
{
pNode1 = pNode1->m_pNext;
}
ListNode* pNode2 = pHead;
while (pNode1 != pNode2)
{
pNode1 = pNode1->m_pNext;
pNode2 = pNode2->m_pNext;
}
*start = pNode1;
return true;
}
pBehind = pBehind->m_pNext;
pAhead = pAhead->m_pNext;
if (pAhead != NULL)
pAhead = pAhead->m_pNext;
}
cout << "List has no loop!" << endl;
*start = NULL;
return false;
}
ListNode* MergeListsOrderly(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL) return pHead2;
else if (pHead2 == NULL) return pHead1;
ListNode* pMergeHead = NULL;
ListNode* pNode = NULL;
if (ListLength(pHead1) >= ListLength(pHead2))
{
pMergeHead = pHead1;
pNode = pHead2;
}
else
{
pMergeHead = pHead2;
pNode = pHead1;
}
ListNode* pNxtNode = NULL;
while (pNode != NULL)
{
pNxtNode = pNode->m_pNext;
pMergeHead = InsertNodeOrderly(pMergeHead, pNode);
pNode = pNxtNode;
}
if (pMergeHead == pHead1) pHead2 = NULL;
else if (pMergeHead == pHead2) pHead1 = NULL;
return pMergeHead;
}
ListNode* InsertNodeOrderly(ListNode* pHead, ListNode* pInsertNode)
{
if (pHead == NULL)
{
pHead = pInsertNode;
return pHead;
}
if (pInsertNode->m_nValue <= pHead->m_nValue)
{
pInsertNode->m_pNext = pHead;
pHead = pInsertNode;
return pHead;
}
ListNode* pCurNode = pHead;
ListNode* pPreNode = NULL;
while (pInsertNode->m_nValue > pCurNode->m_nValue && pCurNode->m_pNext != NULL)
{
pPreNode = pCurNode;
pCurNode = pCurNode->m_pNext;
}
if (pInsertNode->m_nValue <= pCurNode->m_nValue)
{
pPreNode->m_pNext = pInsertNode;
pInsertNode->m_pNext = pCurNode;
}
else pCurNode->m_pNext = pInsertNode;
return pHead;
}
ListNode* MergeListsOrderly_Recursively(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL) return pHead2;
if (pHead2 == NULL) return pHead1;
ListNode* pMergeHead = NULL;
if (pHead1->m_nValue < pHead2->m_nValue)
{
pMergeHead = pHead1;
pMergeHead->m_pNext = MergeListsOrderly_Recursively(pHead1->m_pNext, pHead2);
}
else
{
pMergeHead = pHead2;
pMergeHead->m_pNext = MergeListsOrderly_Recursively(pHead1, pHead2->m_pNext);
}
return pMergeHead;
}
#include <list>
int LastRemaining_Josephuse(unsigned int num, unsigned int kth)
{
if (num < 1 || kth < 1)
{
cout << "Error: invalid input!" << endl;
return -1;
}
std::list<int> numbers;
numbers.clear();
for (int i = 0; i < num; ++i)
numbers.push_back(i);
list<int>::iterator current = numbers.begin();
while (numbers.size() > 1)
{
for (int i = 1; i < kth; ++i)
{
current++;
if (current == numbers.end())
current = numbers.begin();
}
list<int>::iterator next = ++current;
if (next == numbers.end())
next = numbers.begin();
current--;
numbers.erase(current);
current = next;
}
return (*current);
}
ListNode* CreateLoopList()
{
ListNode* pHead = CreateList();
if (pHead == NULL || pHead->m_pNext == NULL)
{
cout << "Can't create a loop list,list is empty or has only one node!" << endl;
return NULL;
}
ListNode* pNode = pHead;
while (pNode->m_pNext != NULL)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = pHead;
return pHead;
}
#include <stack>
void PrintListFromTail_Iteratively(ListNode* pHead)
{
if (pHead == NULL)
{
cout << "List is empty!" << endl;
return;
}
std::stack<ListNode*> nodesStack;
ListNode* pNode = pHead;
while (pNode != NULL)
{
nodesStack.push(pNode);
pNode = pNode->m_pNext;
}
while (!nodesStack.empty())
{
pNode = nodesStack.top();
cout << pNode->m_nValue << " ";
nodesStack.pop();
}
}
void PrintListFromTail_Recursively(ListNode* pHead)
{
if (pHead != NULL)
{
if (pHead->m_pNext != NULL)
{
PrintListFromTail_Recursively(pHead->m_pNext);
}
printf("%d ", pHead->m_nValue);
}
}