如果要转载的话,请声明出处http://blog.youkuaiyun.com/j8121,万分感谢。
ListNode.h文件:
typedef struct ListNode
{
int m_nKey;
ListNode* m_pNext;
}ListNode;
<pre name="code" class="cpp">//编程实现一个单链表的建立
ListNode* ListCreate();
<pre name="code" class="cpp">//单链表的正向排序
ListNode* ListSortCreate();
<pre name="code" class="cpp">//编程实现一个单链表的打印
void ListPrint(ListNode* pHead);
<pre name="code" class="cpp">//编程实现一个单链表的测长
unsigned int GetListLength(ListNode* pHead);
<pre name="code" class="cpp">//编程实现一个单链表节点的插入
ListNode* ListInsert(ListNode* pHead,int pos,int data);
<pre name="code" class="cpp">//编程实现一个单链表节点的查找
ListNode* ListSearch(ListNode* pHead, int pos);
<pre name="code" class="cpp">//编程实现一个单链表节点的删除
ListNode* ListDelete(ListNode* pHead, int pos);
<pre name="code" class="cpp">//查找单链表中的倒数第K个结点(k > 0)(单指针)
ListNode* RGetKthNode1(ListNode* pHead, unsigned int k);
<pre name="code" class="cpp">//查找单链表中的倒数第K个结点(k > 0)(双指针)
ListNode* RGetKthNode2(ListNode* pHead, unsigned int k);
<pre name="code" class="cpp">//寻找单链表的中间元素(单指针)
ListNode* GetMiddleNode1(ListNode* pHead);
<pre name="code" class="cpp">//寻找单链表的中间元素(双指针)
ListNode* GetMiddleNode2(ListNode* pHead);
<pre name="code" class="cpp">//从尾到头打印单链表(递归方法)
void RListPrint1(ListNode* pHead);
<pre name="code" class="cpp">//从尾到头打印单链表(使用栈的方法)
void RListPrint2(ListNode* pHead);
<pre name="code" class="cpp">//实现一个单链表的逆置
ListNode* ListReverse1(ListNode* pHead);
<pre name="code" class="cpp">//判断两个单链表是否相交
bool IsIntersected(ListNode* pHead1, ListNode* pHead2);
<pre name="code" class="cpp">//求两个单链表相交的第一个节点
ListNode* GetFirstCommonNode(ListNode* pHead1, ListNode* pHead2);
<pre name="code" class="cpp">//判断链表是否存在环形链表问题
bool HasCircle(ListNode* pHead);
<pre name="code" class="cpp">//已知一个单链表中存在环,求进入环中的第一个节点
ListNode* GetFirstCircleNode(ListNode* pHead);
<pre name="code" class="cpp">//有序单链表的合并(非递归法)
ListNode* MergeSortedList1(ListNode* pHead1, ListNode* pHead2);
<pre name="code" class="cpp">//有序单链表的合并(递归法)
ListNode* MergeSortedList2(ListNode* pHead1, ListNode* pHead2);
<pre name="code" class="cpp">//给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted
void Delete(ListNode* pHead, ListNode* pToBeDeleted);
</pre><pre name="code" class="cpp">
</pre><pre name="code" class="cpp">ListNode.cpp文件:
<pre name="code" class="cpp">#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<stack>
#include"ListNode.h"
//编程实现一个单链表的建立
ListNode* ListCreate()
{
//初始化头节点
ListNode* pHead = (ListNode*)malloc(sizeof(ListNode));
pHead->m_nKey = 0;
pHead->m_pNext = NULL;
ListNode* pPre = pHead;
unsigned int i = 0; //节点编号
int data = 0;
while (1)
{
if (i == 0)
printf("请输入头节点链表的数据:",i++);
else
printf("请输入第%d个链表的数据:", i++);
scanf("%d", &data);
if (data == 0) //输入数据为0时直接退出
break;
if (i == 1) //链表中第一个节点
{
pHead->m_nKey = data;
continue;
}
else //链表后面的节点
{
ListNode* pNew = (ListNode*)malloc(sizeof(ListNode));
pNew->m_nKey = data;
pPre->m_pNext = pNew; //前一个节点的m_pNext指向新节点
pPre = pPre->m_pNext; //新节点为pPre节点
}
}
pPre->m_pNext = NULL; //退出之后pPre为最后一个节点
return pHead;
}
//单链表的正向排序
ListNode* ListSortCreate()
{
ListNode* pHead = (ListNode*)malloc(sizeof(ListNode));
pHead->m_pNext = NULL;
unsigned int i = 0;
int data = 0;
while (1)
{
if (i==0)
printf("请输入头节点链表的数据:", i++);
else
printf("请输入第%d个节点链表的数据:",i++);
scanf("%d", &data);
if (data==0)
break;
if (i == 1) //如果输入第一个节点是头节点
{
pHead->m_nKey = data;
continue;
}
else //其他节点
{
ListNode* pNew = (ListNode*)malloc(sizeof(ListNode));
pNew->m_nKey = data;
if (pNew->m_nKey <= pHead->m_nKey)<span style="white-space:pre"> </span>//新节点小于头节点
{
pNew->m_pNext = pHead;
pHead = pNew;
}
else //新节点大于头节点
{
ListNode* pPre = NULL,*pCur=pHead;
while (pNew->m_nKey > pCur->m_nKey && pCur->m_pNext != NULL) //找到新节点的位置
{
pPre = pCur;
pCur = pCur->m_pNext;<span style="white-space:pre"> </span><span style="font-family: Arial, Helvetica, sans-serif;">//记录当前节点的前一个节点</span><span style="white-space:pre">
</span> }
if (pNew->m_nKey <= pCur->m_nKey) //中间插入
{
pNew->m_pNext = pCur;
pPre->m_pNext = pNew;
}
else /尾部插入
{
pCur->m_pNext = pNew;
pNew->m_pNext = NULL;
}
}
}
}
return pHead;
}
//编程实现一个单链表的打印
void ListPrint(ListNode* pHead)
{
if (!pHead)
{
printf("List is empty.\n");
return;
}
while (pHead)
{
printf("%p,%p %d\n", pHead,pHead->m_pNext,pHead->m_nKey);
pHead = pHead->m_pNext;
}
}
//编程实现一个单链表的测长(单指针)
unsigned int GetListLength(ListNode* pHead)
{
if (!pHead) //头节点的有效性
return 0;
unsigned int index = 0; //记数
ListNode* pCur = pHead;
while (pCur)
{
index++;
pCur = pCur->m_pNext;<span style="white-space:pre"> </span>//迭代
}
printf("Length1 of List is %u\n", index);
return index;
}
//编程实现一个单链表节点的查找
ListNode* ListSearch(ListNode* pHead, int pos)
{
int tempPos = pos;
if (!pHead) //有效性
return NULL;
if (tempPos < 0)<span style="white-space:pre"> </span>//pos的有效性
{
printf("pos < 0, not search.\n");
return pHead;
}
else if (!tempPos) //0返回头节点
return pHead;
else
{
while (tempPos && pHead)
{
pHead = pHead->m_pNext;
tempPos--;
}
if (!pHead)
{
printf("not find %d pos.\n", pos);
return NULL;
}
else
{
printf("find:%p %p %d\n", pHead, pHead->m_pNext, pHead->m_nKey);
return pHead;
}
}
}
//编程实现一个单链表节点的插入
ListNode* ListInsert(ListNode* pHead, int pos,int data)
{
if (!pHead) //有效性
return NULL;
if (pos < 0) //pos小于0不能插入
{
printf("pos < 0,not insert.\n");
return pHead;
}
ListNode* pNew = (ListNode*)malloc(sizeof(ListNode));
pNew->m_nKey = data;
if (!pos) //插在头节点之前
{
pNew->m_pNext = pHead;
return pNew;
}
else
{
ListNode* pCur = pHead;
ListNode* pPre = pHead;
while (pos && pCur)
{
pPre = pCur; //链表结尾,保存最后一个节点
pCur = pCur->m_pNext;
pos--;
}
if (!pCur)
{
pPre->m_pNext = pNew; //尾部插入
pNew->m_pNext = NULL;
}
else
{
pNew->m_pNext = pCur->m_pNext; //中间插入
pCur->m_pNext = pNew;
}
return pHead;
}
}
//编程实现一个单链表节点的删除
ListNode* ListDelete(ListNode* pHead, int pos)
{
if (!pHead) //有效性
return NULL;
if (pos < 0) //pos的有效性
{
printf("pos < 0 ,not Delete.\n");
return pHead;
}
ListNode* pDel = pHead;
if (!pos) //删除第0个节点(头节点)
{
pHead = pHead->m_pNext;
free(pDel);
}
else
{
ListNode* pPre = ListSearch(pHead, pos - 1);<span style="white-space:pre"> </span>//删除中间节点
if (pPre && pPre->m_pNext)
{
pDel = pPre->m_pNext;
pPre->m_pNext = pDel->m_pNext; //删除节点的前一个节点指向删除节点的后一个节点
free(pDel);
}
}
return pHead;
}
//编程实现查找倒数第K个节点(k>0)(单指针)
ListNode* RGetKthNode1(ListNode* pHead, unsigned int k)
{
if (k == 0 || pHead == NULL)
{
printf("k = 0,ListNode is empty.\n");
return NULL;
}
ListNode* pCur = pHead;
unsigned int length = GetListLength(pHead);<span style="white-space:pre"> </span>//获取长度
while (length - k >= 0 && pCur->m_pNext == NULL)<span style="white-space:pre"> </span>//执行length-k次,或者pCur指向最后
{
pCur = pCur->m_pNext;
k++;
}
if (pCur == NULL)
{
printf("final ListNode.\n"); //到链表最后一个节点,没有找到
return NULL;
}
return pCur;
}
//编程实现查找倒数第K个节点(k > 0)(双指针)
ListNode* RGetKthNode2(ListNode* pHead, unsigned int k)
{
if (k == 0 || pHead == NULL) //k,pHead的有效性
{
printf("k = 0,ListNode is empty.\n");
return NULL;
}
ListNode* pAhead = pHead;
ListNode* pBehind = pHead;
while (k > 0 && pAhead->m_pNext != NULL)<span style="white-space:pre"> </span>//前指针先走k步
{
pAhead = pAhead->m_pNext;
k--;
}
if (pAhead == NULL) //排除k为第一个情况
{
printf("final ListNode.\n");
return NULL;
}
while (pAhead->m_pNext != NULL) //前指针到结尾
{
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
//寻找单链表的中间元素(单指针)
ListNode* GetMiddleNode1(ListNode* pHead)
{
if (pHead == NULL)<span style="white-space:pre"> </span>//链表有效性
{
printf("List is empty.\n");
return NULL;
}
ListNode* pCur = pHead;
unsigned int length = GetListLength(pHead) / 2; //长度的一半
while (length >= 0) //指针前进长度一半
{
pCur = pCur->m_pNext;
length--;
}
return pCur;
}
//寻找单链表的中间元素(双指针)
ListNode* GetMiddleNode2(ListNode* pHead)
{
if (pHead == NULL) //List的有效性
{
printf("List is empty.\n");
return NULL;
}
ListNode* pAhead = pHead;<span style="white-space:pre"> </span>//快指针
ListNode* pBehind = pHead; //慢指针
while (pAhead->m_pNext != NULL)
{
pAhead = pAhead->m_pNext; //快指针每次走两步
pBehind = pBehind->m_pNext; //慢指针每次走一步
if (pAhead->m_pNext != NULL) //快指针下一个节点有效性
pAhead = pAhead->m_pNext;
}
return pBehind;
}
//从尾到头打印单链表(递归方法)
void RListPrint1(ListNode* pHead)
{
if (pHead == NULL) //有效性,最后递归到最后一个为NULL的节点
return ;
if (pHead !=NULL)
{
RListPrint1(pHead->m_pNext); //递归调用
printf("%p %p %d\n", pHead->m_pNext, pHead, pHead->m_nKey);
}
return;
}
//从尾到头打印单链表(使用栈)
void RListPrint2(ListNode* pHead)
{
if (pHead == NULL) //有效性
{
printf("List is empty.\n");
return ;
}
std::stack<ListNode* > s; //栈
while (pHead != NULL)
{ //节点不为NULL,就压入栈,最后的节点在栈顶
s.push(pHead);
pHead = pHead->m_pNext;
}
ListNode* pCur = s.top();
while (!s.empty()) //打印栈顶元素
{
pCur = s.top(); //pCur指向栈顶
printf("%p %p %d\n", pCur->m_pNext, pCur, pCur->m_nKey);
s.pop();<span style="white-space:pre"> </span>//弹出
}
return;
}
//实现一个单链表的逆置
ListNode* ListReverse1(ListNode* pHead)
{
if (pHead == NULL)
{
printf("List is empty.\n");
return NULL;
}
ListNode* pReverseHead = NULL;
ListNode* pCur = pHead;
while (pCur != NULL)
{
ListNode* pTemp = pCur; //拷贝当前转置节点,pTemp为要转置的节点
pCur = pCur->m_pNext; //保存下一个需要转置的节点
pTemp->m_pNext = pReverseHead; //转置节点指向前面节点
pReverseHead = pTemp; //前节点变为转置节点
}
return pReverseHead;
}
//判断两个单链表是否相交
bool IsIntersected(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1== NULL || pHead2 == NULL)
{
printf("pHead1 or pHead2 is empty.\n");
return NULL;
}
while (pHead1->m_pNext != NULL)
pHead1 = pHead1->m_pNext;
while (pHead2->m_pNext != NULL)
pHead2 = pHead2->m_pNext;
return pHead1 == pHead2;
}
//求两个单链表相交的第一个节点
ListNode* GetFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL || pHead2 == NULL)
{
printf("pHead1 or pHead2 is empty.\n");
return NULL;
}
unsigned int len1 = GetListLength(pHead1);
/*ListNode* pTail1 = pHead1;
while (pTail1->m_pNext)
{
pTail1 = pTail1->m_pNext;
len1++;
}*/
unsigned int len2 = GetListLength(pHead2);
//ListNode* pTail2 = pHead2;
//while (pTail2->m_pNext)
//{
// pTail2 = pTail2->m_pNext;
// len2++;
//}
ListNode* pTail1 = pHead1;
ListNode* pTail2 = pHead2;
if (len1 - len2 >= 0) //pHead1比pHead2长
{
int k = len1 - len2;
while (k--) //pHead1先走len1-len2长度
pTail1 = pTail1->m_pNext;
}
else
{
int k = len2 - len1; //pHead2先走len1-len2长度
while (k--)
pTail2 = pTail2->m_pNext;
}
while (pTail1 != pTail2)<span style="white-space:pre"> </span>//节点不相等继续遍历下节点,直到到末尾NULL或者相等
{
pTail1 = pTail1->m_pNext;
pTail2 = pTail2->m_pNext;
}
if (pTail1 == pTail2 == NULL) //到了末尾
return NULL;
return pTail1; //相等
}
//判断链表是否存在环形链表问题
bool HasCircle(ListNode* pHead)
{
ListNode* pFast = pHead, *pSlow = pHead;
while (pFast != NULL && pFast->m_pNext != NULL) //即判断有效性,也是终止循环条件
{
pFast = pFast->m_pNext->m_pNext;
pSlow = pSlow->m_pNext;
if (pFast == pSlow) //快慢指针相遇
return true;
}
return false;
}
//已知一个单链表中存在环,求进入环中的第一个节点
ListNode* GetFirstCircleNode(ListNode* pHead)
{
if (pHead == NULL) //头节点的有效性
{
printf("List is empty.\n");
return NULL;
}
if (HasCircle(pHead) == false) //List是否存在环
{
printf("List is Circle List.\n");
return NULL;
}
ListNode* pFast = pHead, *pSlow = pHead;//快指针走两步,慢指针走一步
do //此处使用do...while循环
{
pFast = pFast->m_pNext->m_pNext;
pSlow = pSlow->m_pNext;
} while (pFast != pSlow);
pSlow = pHead; //从头节点在发出慢指针
while (pSlow != pFast) //两个节点相遇,返回此节点
{
pSlow = pSlow->m_pNext;
pFast = pFast->m_pNext;
}
return pSlow;
}
//有序单链表的合并(非递归法) 1、有效性的校验 2、确定头节点 3、合并 4、一个链表为空则指向另一个链表
ListNode* MergeSortedList1(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL) //链表1有效性
{
printf("List1 is empty.\n");
return pHead2;
}
if (pHead2 == NULL) //链表2有效性
{
printf("List2 is empty.\n");
return pHead1;
}
ListNode* MergeList = NULL; //合并之后的链表
if (pHead1->m_nKey <= pHead2->m_nKey) //判断头节点是链表1头节点还是链表2头节点
{
MergeList = pHead1;
pHead1 = pHead1->m_pNext;
}
else
{
MergeList = pHead2;
pHead2 = pHead2->m_pNext;
}
MergeList->m_pNext = NULL;
ListNode* pTemp = MergeList;
while (pHead1 != NULL && pHead2 != NULL)<span style="white-space:pre"> </span>//合并链表后续节点
{
if (pHead1->m_nKey <= pHead2->m_nKey) //链表1节点小于链表2节点
{
pTemp->m_pNext = pHead1;
pHead1 = pHead1->m_pNext;
}
else
{
pTemp->m_pNext = pHead2; //相反情况
pHead2 = pHead2->m_pNext;
}
pTemp = pTemp->m_pNext; //pTemp指向MergeList的下一个节点
pTemp->m_pNext = NULL; //将MergeList的pNext指针置为空
}
if (pHead1 == NULL) //链表1比2短,则后续节点为链表2的所有节点
pTemp->m_pNext = pHead2;
else //反之
pTemp->m_pNext = pHead1;
return MergeList;
}
//有序单链表的合并(递归法)
ListNode* MergeSortedList2(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL) //链表1有效性同时也是递归终止条件:返回长链表的剩余所有节点
{
printf("List1 is empty.\n");
return pHead2;
}
if (pHead2 == NULL) //链表2有效性
{
printf("List2 is empty.\n");
return pHead1;
}
ListNode* MergeList = NULL; //合并链表
if (pHead1->m_nKey <= pHead2->m_nKey)
{
MergeList = pHead1; //当前节点为链表1节点,同时也是下一个节点的上一级节点
MergeList->m_pNext = MergeSortedList2(pHead1->m_pNext, pHead2); //链表1节点的下一节点与链表2当前节点比较,返回下一个节点
}
else
{
MergeList = pHead2; //同理
MergeList->m_pNext = MergeSortedList2(pHead1, pHead2->m_pNext);
}
return MergeList; //返回两个节点中较小的节点
}
//给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted
void Delete(ListNode** pHead, ListNode* pToBeDeleted)
{
if (!pHead || !pToBeDeleted) //链表的有效性
return;
if (pToBeDeleted->m_pNext != NULL)<span style="white-space:pre"> </span>//删除节点在中间
{
ListNode* pTemp = pToBeDeleted->m_pNext;
pToBeDeleted->m_nKey = pToBeDeleted->m_pNext->m_nKey;
pToBeDeleted->m_pNext = pToBeDeleted->m_pNext->m_pNext;
delete pTemp;
pTemp = NULL;
}
else if (*pHead == pToBeDeleted)<span style="white-space:pre"> </span>//删除节点在头节点
{
delete pToBeDeleted;
pToBeDeleted = NULL;
*pHead = NULL;
}
else
{ //删除节点在尾节点
ListNode* ptemp = *pHead;
while (ptemp->m_pNext != pToBeDeleted)
ptemp = ptemp->m_pNext;
ptemp->m_pNext = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
main.cpp文件(测试代码):
<pre name="code" class="cpp">#include"ListNode.h"
#include<stdlib.h>
#include<stdio.h>
//编程实现一个单链表的打印
void main()
{
/*ListNode* pHead = ListCreate();
ListPrint(pHead);*/
//ListNode* pHead1 = GetMiddleNode1(pHead);
//ListPrint(pHead1);
//printf("\n\n");
//ListNode* pHead2 = GetMiddleNode2(pHead);
//ListPrint(pHead2);
/*printf("\n\n");*/
//RListPrint1(pHead);
//printf("\n\n");
//RListPrint2(pHead);
//printf("\n\n");
//ListNode* ReHead1 = ListReverse1(pHead);
//ListPrint(ReHead1);
//GetListLength(pHead);
//ListInsert(pHead, 4, 80);
//ListSearch(pHead, 9);
//pHead = ListDelete(pHead, 3);
//ListPrint(pHead);
//ListNode* pKth1 = RGetKthNode1(pHead, 1);
//ListPrint(pKth1);
//printf("\n");
//ListNode* pKth2 = RGetKthNode2(pHead, 1);
//ListPrint(pKth2);
//ListNode e = { 1, 0 }, d = { 2, &e }, c = { 3, &d }, b = 4, &c }, a = { 5, &b };
//ListNode z = { 6, &c }, y = { 7, &z }, x = { 8, &y };
///*k = 2 * n - x;*/
//printf("%d\n", IsIntersected(&a, &x));
/*ListNode* pHead = ListSortCreate();
ListPrint(pHead);*/
ListNode e = { 1, 0 }, d = { 2, &e }, c = { 10, &d }, b = { 4, &c }, a = { 5, &b };
ListNode z = { 6, &c }, y = { 7, &z }, x = { 8, &a };
printf("%d", GetFirstCommonNode(&a, &x)->m_nKey);
/*ListNode i = { 11, 0 }, h = { 12, &i }, g = { 15, &h }, f = { 17, &g }, e = { 19, &f }, d = { 2, &e }, c = { 10, &d }, b = { 4, &c }, a = { 5, &b };
i.m_pNext = &d;
printf("%d", HasCircle(&a));*/
//ListNode i = { 11, 0 }, h = { 12, &i }, g = { 15, &h }, f = { 17, &g }, e = { 19, &f }, d = { 2, &e }, c = { 10, &d }, b = { 4, &c }, a = { 5, &b };
//i.m_pNext = &d;
//printf("%d", GetFirstCircleNode(&a)->m_nKey);
/*ListNode i = { 35, 0 }, h = { 28, &i }, g = { 25, &h }, f = { 21, &g }, e = { 19, &f }, d = { 11, &e }, c = { 10, &d }, b = { 4, &c }, a = { 1, &b };
ListNode i1 = { 36, 0 }, h1 = { 29, &i1 }, g1 = { 27, &h1 }, f1 = { 24, &g1 }, e1 = { 22, &f1 }, d1 = { 18, &e1 }, c1 = { 16, &d1 }, b1 = { 15, &c1 }, a1 = { 6, &b1 };
ListNode* pMergeHead = MergeSortedList2(&a, &a1);
ListPrint(pMergeHead);*/
system("pause");
}