在这里简单实现了单链表的基本操作,重点实现单链表的各种面试题。
代码如下:
头文件LinkList.h:
#ifndef __LinkList_H__ #define __LinkList_H__ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> typedef int DataType; typedef struct Node { DataType data; struct Node *next; }Node,*pNode; void InitList(pNode *pHead); //初始化链表 void PushBack(pNode *pHead,DataType data); //尾插 void PopBack(pNode *pHead); //尾删 void PushFront(pNode *pHead,DataType data); //头插 void PopFront(pNode *pHead); //头删 pNode Find(pNode pHead,DataType data); //查找结点位置 void Insert(pNode pos,DataType data); //在指定位置插入结点 pNode BuyNode(DataType data); //创建新结点 void DestroyList(pNode *pHead); //销毁链表 pNode Back(pNode pHead); //返回最后一个结点地址 void PrintList(pNode pHead); //打印链表 int Size(pNode pHead); //求链表中结点个数 ////////////链表面试题///////////// void PrintFromT2H(pNode pHead); //逆序打印链表 void DeleteNotTail(pNode pos); //删除无头结点非尾结点的指定位置结点 void InsertNotHead(pNode pHead,pNode pos,DataType data);//无头指针在当前结点前插入一个结点 void JosphCircle(pNode *pHead,int M); //约瑟夫环问题 pNode FindMidNode(pNode pHead); //查找中间结点返回其地址 pNode FindLastKNode(pNode pHead,int k); //查找倒数第k个结点 void ReverseList(pNode *pHead); //反转链表 void BubbleSort(pNode pHead); //冒泡排序 pNode MergeList(pNode pList1,pNode pList2); //合并两有序链表后依有序 int IsCross(pNode pHead1,pNode pHead2); //判断两链表是否相交 pNode GetCrossNode(pNode pHead1,pNode pHead2);//若两链表相交,求交点 pNode HasCircle(pNode pHead); //判断链表是否带环 int GetCircleLen(pNode pMeetNode); //求环的长度 pNode GetEnterNode(pNode pHead,pNode pMeetNode); //获取环的入口点 int IsCrossWithCircle(pNode pHead1,pNode pHead2);//判断带环链表是否相交 pNode UnionSet(pNode pHead1,pNode pHead2); //求两个已排序单链表中相同的数据打印出来 #endif __LinkList_H__
#include "LinkList.h" void InitList(pNode *pHead) //初始化链表 { assert(pHead); *pHead=NULL; } void PushBack(pNode *pHead,DataType data) //尾插 { assert(pHead); if(*pHead==NULL) { *pHead=BuyNode(data); } else { pNode cur=*pHead; while(cur->next!=NULL) { cur=cur->next; } cur->next=BuyNode(data); } } void PopBack(pNode *pHead) //尾删 { assert(pHead); if(*pHead==NULL) { return; } else if((*pHead)->next==NULL) { free(*pHead); *pHead=NULL; } else { pNode cur=*pHead; pNode prev=cur; while(cur->next) { prev=cur; cur=cur->next; } free(cur); cur=NULL; prev->next=NULL; } } void PushFront(pNode *pHead,DataType data) //头插 { pNode cur=NULL; assert(pHead); if(*pHead==NULL) { *pHead=BuyNode(data); } else { cur=BuyNode(data); cur->next=*pHead; *pHead=cur; } } void PopFront(pNode *pHead) //头删 { assert(pHead); if(*pHead==NULL) { return; } else if((*pHead)->next==NULL) { free(*pHead); *pHead=NULL; } else { pNode cur=*pHead; *pHead=cur->next; free(cur); cur=NULL; } } pNode Find(pNode pHead,DataType data) //查找结点位置 { pNode pos=NULL; assert(pHead); pos=pHead; while(pos) { if((pos->data)==data) { return pos; } pos=pos->next; } return NULL; } void Insert(pNode pos,DataType data) //在指定位置插入结点 { pNode cur=NULL; if(pos==NULL) { return; } cur=BuyNode(data); cur->next=pos->next; pos->next=cur; } pNode BuyNode(DataType data) //创建新结点 { pNode newNode=(pNode)malloc(sizeof(Node)); if(NULL==newNode) { printf("out of memory\n"); exit(EXIT_FAILURE); } newNode->data=data; newNode->next=NULL; return newNode; } void PrintList(pNode pHead) //打印链表 { pNode cur=NULL; assert(pHead); cur=pHead; while(cur) { printf("%d-->",cur->data); cur=cur->next; } printf("\n"); } void DestroyList(pNode *pHead) //销毁链表 { pNode cur=*pHead; assert(pHead); while(cur) { pNode del=cur; cur=cur->next; free(del); del=NULL; } *pHead=NULL; } pNode Back(pNode pHead) //返回最后一个结点地址 { pNode cur=pHead; pNode tail=NULL; while(cur) { tail=cur; cur=cur->next; } return tail; } void PrintFromT2H(pNode pHead) //逆序打印链表 { pNode cur=pHead; if(pHead!=NULL) { PrintFromT2H(cur->next); printf("<--%d",cur->data); } } void DeleteNotTail(pNode pos) //删除无头结点非尾结点的指定位置结点 { pNode del=NULL; if(pos==NULL||pos->next==NULL) { return; } del=pos->next; pos->data=del->data; pos->next=del->next; free(del); del=NULL; } void InsertNotHead(pNode pHead,pNode pos,DataType data) //在当前结点前插入一个结点 { assert(pHead); if(pos!=NULL&&pos!=pHead) { pNode newNode=BuyNode(data); newNode->next=pos->next; pos->next=newNode; newNode->data=pos->data; pos->data=data; } } void JosphCircle(pNode *pHead,int M) //约瑟夫环问题 { pNode curpos=*pHead; pNode del=NULL; while(curpos!=curpos->next) { int count=M; while(--count) { curpos=curpos->next; } del=curpos->next; curpos->next=del->next; curpos->data=del->data; free(del); del=NULL; } *pHead=curpos; } pNode FindMidNode(pNode pHead) //查找中间结点返回其地址 { pNode slow=pHead; pNode fast=pHead; if(pHead==NULL) { return; } while(fast!=NULL&&fast->next!=NULL) { slow=slow->next; fast=fast->next->next; } return slow; } pNode FindLastKNode(pNode pHead,int k) //查找倒数第k个结点 { pNode back=pHead; pNode front=pHead; if(pHead==NULL||k<1) { return; } while(--k) { front=front->next; } while(front->next!=NULL) { front=front->next; back=back->next; } return back; } void ReverseList(pNode *pHead) //反转链表 { pNode cur=*pHead; pNode tmp=NULL; pNode newHead=NULL; if(NULL==*pHead||NULL==(*pHead)->next) { return; } while(cur) { tmp=cur; cur=cur->next; tmp->next=newHead; newHead=tmp; } *pHead=newHead; } void BubbleSort(pNode pHead) //冒泡排序 { pNode cur=pHead; pNode tail=NULL; int flag=1; if(NULL==pHead||NULL==pHead->next) { return; } while(cur!=tail) { flag=1; while(cur->next!=tail) { if(cur->data>cur->next->data) { DataType tmp=cur->data; cur->data=cur->next->data; cur->next->data=tmp; flag=0; } cur=cur->next; } tail=cur; cur=pHead; if(flag) { break; } } } pNode MergeList(pNode pList1,pNode pList2) //合并两有序链表后依有序 { pNode pNode1=pList1; pNode pNode2=pList2; pNode pNewNode=NULL; pNode pTailNode=NULL; if(pList1==NULL) { return pList2; } if(pList2==NULL) { return pList1; } if(pNode1->data < pNode2->data) { pNewNode=pNode1; pNode1=pNode1->next; } else { pNewNode=pNode2; pNode2=pNode2->next; } pTailNode=pNewNode; while(pNode1!=NULL&&pNode2!=NULL) { if(pNode1->data < pNode2->data) { pTailNode->next=pNode1; pNode1=pNode1->next; } else { pTailNode->next=pNode2; pNode2=pNode2->next; } pTailNode=pTailNode->next; } if(pNode1==NULL) { pTailNode->next=pNode2; } if(pNode2==NULL) { pTailNode->next=pNode1; } return pNewNode; } int IsCross(pNode pHead1,pNode pHead2) //判断两链表是否相交 { pNode pNode1=pHead1; pNode pNode2=pHead2; if(pHead1==NULL||pHead2==NULL) { return -1; } while(pNode1->next) { pNode1=pNode1->next; } while(pNode2->next) { pNode2=pNode2->next; } if(pNode1==pNode2) { return 1; } return -1; } pNode GetCrossNode(pNode pHead1,pNode pHead2) //若两链表相交,求交点 { if(IsCross(pHead1,pHead2)==1) { pNode pNode1=pHead1; pNode pNode2=pHead2; int len1=0; int len2=0; int step=0; len1=Size(pHead1); len2=Size(pHead2); step=len1-len2; if(step>0) { while(step--) { pNode1=pNode1->next; } } else { step=0-step; while(step--) { pNode2=pNode2->next; } } while(pNode1!=pNode2) { pNode1=pNode1->next; pNode2=pNode2->next; } return pNode1; } else { return NULL; } } int Size(pNode pHead) //求链表中结点个数 { int count=0; pNode cur=pHead; while(cur) { cur=cur->next; count++; } return count; } pNode HasCircle(pNode pHead) //判断链表是否带环 { pNode pSlow=pHead; pNode pFast=pHead; assert(pHead); while(pFast&&pFast->next) { pFast=pFast->next->next; pSlow=pSlow->next; if(pSlow==pFast) { return pSlow; } } return NULL; } int GetCircleLen(pNode pMeetNode) //求环的长度 { int count=1; pNode pNext=pMeetNode; if(pMeetNode==NULL) { return 0; } while(pNext->next!=pMeetNode) { count++; pNext=pNext->next; } return count; } pNode GetEnterNode(pNode pHead,pNode pMeetNode) //获取环的入口点 { pNode pSlow=pHead; pNode pFast=pMeetNode; assert(pHead); if(pMeetNode==NULL) { return NULL; } while(pSlow!=pFast) { pSlow=pSlow->next; pFast=pFast->next; } return pSlow; } int IsCrossWithCircle(pNode pHead1,pNode pHead2) //判断两个带环链表是否相交 { pNode PM1=HasCircle(pHead1); pNode PM2=HasCircle(pHead2); if(PM1!=NULL&&PM2!=NULL) { pNode pNext=PM1; if(pNext==PM2) { return 1; } pNext=pNext->next; while(pNext!=PM1) { if(pNext==PM2) { return 1; } pNext=pNext->next; } return 0; } } pNode UnionSet(pNode pHead1,pNode pHead2) //求两个已排序单链表中相同的数据打印出来 { pNode pNode1=pHead1; pNode pNode2=pHead2; pNode pNewNode=NULL; pNode pTailNode=NULL; if(pHead1==NULL||pHead2==NULL) { return; } while(pNode1->data!=pNode2->data) { if(pNode1==NULL||pNode2==NULL) { return; } if(pNode1->data<pNode2->data) { pNode1=pNode1->next; } else { pNode2=pNode2->next; } } pNewNode=pNode1; pNode1=pNode1->next; pNode2=pNode2->next; pTailNode=pNewNode; while(pNode1!=NULL&&pNode2!=NULL) { if(pNode1->data<pNode2->data) { pNode1=pNode1->next; } else if(pNode1->data>pNode2->data) { pNode2=pNode2->next; } else { if(pNode1->data!=pTailNode->data) { pTailNode->next=pNode1; pNode1=pNode1->next; pNode2=pNode2->next; pTailNode=pTailNode->next; } else { pNode1=pNode1->next; pNode2=pNode2->next; } } } if(pNode1==NULL||pNode2==NULL) { pTailNode->next=NULL; } return pNewNode; }
#include "LinkList.h" void test1() { pNode pHead; InitList(&pHead); PushBack(&pHead,1); PushBack(&pHead,2); PushBack(&pHead,3); PushBack(&pHead,4); PushBack(&pHead,5); PrintList(pHead); PopBack(&pHead); PrintList(pHead); PopBack(&pHead); PrintList(pHead); DestroyList(&pHead); } void test2() { pNode pHead; InitList(&pHead); PushFront(&pHead,5); PushFront(&pHead,4); PushFront(&pHead,3); PushFront(&pHead,2); PushFront(&pHead,1); PrintList(pHead); PopFront(&pHead); PrintList(pHead); PopFront(&pHead); PrintList(pHead); DestroyList(&pHead); } void test3() { pNode pHead; InitList(&pHead); PushBack(&pHead,1); PushBack(&pHead,2); PushBack(&pHead,3); PushBack(&pHead,4); PushBack(&pHead,5); Insert(Find(pHead,3),6); PrintList(pHead); Insert(Find(pHead,5),7); PrintList(pHead); DestroyList(&pHead); } void test4() { pNode pHead; pNode mid; InitList(&pHead); PushBack(&pHead,1); PushBack(&pHead,2); PushBack(&pHead,3); PushBack(&pHead,4); PrintList(pHead); //PrintFromT2H(pHead); InsertNotHead(pHead,Find(pHead,4),5); PrintList(pHead); DeleteNotTail(Find(pHead,5)); PrintList(pHead); mid=FindMidNode(pHead); printf("%d\n",mid->data); DestroyList(&pHead); } void test5() { pNode pHead; pNode tail; InitList(&pHead); PushBack(&pHead,1); PushBack(&pHead,2); PushBack(&pHead,3); PushBack(&pHead,4); PushBack(&pHead,5); PushBack(&pHead,6); PushBack(&pHead,7); PushBack(&pHead,8); PrintList(pHead); tail=Back(pHead); tail->next=pHead; JosphCircle(&pHead,3); pHead->next=NULL; PrintList(pHead); DestroyList(&pHead); } void test6() { pNode pHead; InitList(&pHead); PushBack(&pHead,1); PushBack(&pHead,7); PushBack(&pHead,4); PushBack(&pHead,3); PushBack(&pHead,5); PushBack(&pHead,2); PushBack(&pHead,8); PushBack(&pHead,6); PrintList(pHead); ReverseList(&pHead); PrintList(pHead); BubbleSort(pHead); PrintList(pHead); DestroyList(&pHead); } void test7() { pNode pHead1; pNode pHead2; pNode pHead; InitList(&pHead1); InitList(&pHead2); PushBack(&pHead1,1); PushBack(&pHead1,3); PushBack(&pHead1,4); PushBack(&pHead1,7); PrintList(pHead1); PushBack(&pHead2,2); PushBack(&pHead2,5); PushBack(&pHead2,6); PushBack(&pHead2,8); PrintList(pHead2); pHead=MergeList(pHead1,pHead2); PrintList(pHead); DestroyList(&pHead); } void test8() { pNode pHead1; pNode pHead2; pNode pNode1; pNode pNode2; pNode Node; InitList(&pHead1); InitList(&pHead2); PushBack(&pHead1,1); PushBack(&pHead1,3); PushBack(&pHead1,4); PushBack(&pHead1,7); pNode1=Back(pHead1); PushBack(&pHead2,2); PushBack(&pHead2,5); PushBack(&pHead2,6); PushBack(&pHead2,8); pNode2=Find(pHead2,6); pNode1->next=pNode2; PrintList(pHead1); PrintList(pHead2); Node=GetCrossNode(pHead1,pHead2); PrintList(Node); DestroyList(&pHead1); DestroyList(&pHead2); } void test9() { pNode pHead; pNode Node1; pNode Node2; pNode Node3; InitList(&pHead); PushBack(&pHead,1); PushBack(&pHead,2); PushBack(&pHead,3); PushBack(&pHead,4); PushBack(&pHead,5); PushBack(&pHead,6); PushBack(&pHead,7); PushBack(&pHead,8); PrintList(pHead); Node1=Find(pHead,5); Node2=Back(pHead); Node2->next=Node1; printf("%d\n",GetCircleLen(HasCircle(pHead))); Node3=GetEnterNode(pHead,HasCircle(pHead)); printf("%d\n",Node3->data); } void test10() { pNode pHead1,pHead2; pNode Node1,Node2,Node3,Node4; InitList(&pHead1); InitList(&pHead2); PushBack(&pHead1,1); PushBack(&pHead1,2); PushBack(&pHead1,3); PushBack(&pHead1,4); PushBack(&pHead1,5); PushBack(&pHead1,6); PushBack(&pHead1,7); PushBack(&pHead1,8); PushBack(&pHead2,9); PushBack(&pHead2,0); PushBack(&pHead2,1); PushBack(&pHead2,2); PrintList(pHead1); PrintList(pHead2); Node1=Find(pHead1,5); Node2=Back(pHead1); Node3=Find(pHead1,4); Node4=Back(pHead2); Node2->next=Node1; Node4->next=Node3; printf("%d\n",IsCrossWithCircle(pHead1,pHead2)); } void test11() { pNode pHead1,pHead2; InitList(&pHead1); InitList(&pHead2); PushBack(&pHead1,1); PushBack(&pHead1,3); PushBack(&pHead1,5); PushBack(&pHead1,7); PushBack(&pHead1,9); PushBack(&pHead2,2); PushBack(&pHead2,3); PushBack(&pHead2,3); PushBack(&pHead2,5); PushBack(&pHead2,8); PushBack(&pHead2,9); PrintList(pHead1); PrintList(pHead2); PrintList(UnionSet(pHead1,pHead2)); DestroyList(&pHead1); DestroyList(&pHead2); } int main() { //test1(); //test2(); //test3(); //test4(); //test5(); //test6(); //test7(); //test8(); test9(); test10(); test11(); system("pause"); return 0; }