C语言实现单链表

来源:互联网 发布:规律转移矩阵 编辑:程序博客网 时间:2024/06/05 17:15
#include<stdio.h>#include<malloc.h>#include<assert.h>typedef int DataType;typedef struct Node{DataType data;//数据域struct Node* next;//保存下一个节点地址的指针域}Node,*PNode;void InitList(PNode* pHead)//初始化 传二级指针{assert(pHead);*pHead = NULL;}PNode BuyNode(DataType data)//申请新节点{PNode pTemp = (PNode)malloc(sizeof(Node));//申请空间if(pTemp)//空间申请成功,若不成功直接返回NULL{pTemp->data = data;pTemp->next = NULL;}return pTemp;}void PushBack(PNode* pHead, DataType data)//尾插{assert(pHead);if(*pHead == NULL)//空链表{*pHead = BuyNode(data);}else//链表不为空{PNode pcur = *pHead;while(pcur->next){pcur = pcur->next;}pcur->next = BuyNode(data);}}void PopBack(PNode* pHead)//尾删{assert(pHead);if(*pHead == NULL)//链表为空{return;}else if((*pHead)->next == NULL)//链表只有一个节点{free(*pHead);*pHead = NULL;}else//链表有多个节点{PNode pcur = *pHead;PNode pre = pcur;while(pcur->next){pre = pcur;pcur = pcur->next;}free(pcur);pre->next = NULL;}}void PrintList(PNode pHead)//正序打印 不需二级指针,不改变外部实参{PNode pcur = pHead;while(pcur){printf("%d->",pcur->data);pcur = pcur->next;}printf("NULL\n");}///////////////////////////////////面试题1//////单链表逆置打印 递归//////////////////////////////////////////void PrintTail2Head(PNode pHead){if(pHead){PrintTail2Head(pHead->next);printf("%d->",pHead->data);}}void PushFront(PNode* pHead, DataType data)//头插{assert(pHead);if(*pHead == NULL)//空链表与下面的非空情况可以合并到一起{*pHead = BuyNode(data);}else{PNode newnode = BuyNode(data);if(newnode)//必须判断新节点是否创建成功,成功才可以插入{newnode->next = *pHead;//先将节点链接起来,否则可能丢失原链表    *pHead = newnode;//然后让第一个节点的指针再指向新节点}}}void PopFront(PNode* pHead)//头删{assert(pHead);if(pHead == NULL)//分两种情况 链表为空{return;}//非空else{    PNode pTemp = *pHead;//先保存第一个节点    *pHead = (*pHead)->next;//再让第一个节点向后移动    free(pTemp);//释放掉第一个节点    pTemp = NULL;}}PNode Find(PNode pHead, DataType data)//查找data元素的位置{PNode pTemp = pHead;while(pTemp){if(pTemp->data == data){return pTemp;}pTemp = pTemp->next;}return NULL;//不存在返回空}void Insert(PNode pos, DataType data)//在pos位置后插入元素{PNode newnode = NULL;//为啥要先赋空???if(pos == NULL)//插入位置是否合法{return;}    newnode = BuyNode(data);//先申请新节点newnode->next = pos->next;//让新节点的next指向pos的nextpos->next = newnode;//然后让pos的next指向新节点}void Erase(PNode* pHead, PNode pos)//要给出外部头指针。因为pos若为头结点 有可能改变头结点的值{assert(pHead);//链表是否存在if(pHead == NULL || pos == NULL)//链表为空或位置不合法{return;}if(pos == *pHead)//删除位置为头结点{*pHead = pos->next;//头结点后移free(pos);//删除头节点}else{PNode pcur = *pHead;while(pcur->next != pos){pcur = pcur->next;}pcur->next = pos->next;free(pos);}}/////////////////////////////////面试题2////////删除非尾节点,不能遍历链表 其实是删除pos的下一个节点//////////////////void DelNotTail(PNode pos){PNode Delnode =NULL;if(NULL == pos || pos->next ==NULL)return;Delnode = pos->next;pos->data = Delnode->data;pos->next = Delnode->next;free(Delnode);}/////////////////////////////////面试题3/////////////在非头结点前插入元素(头结点也可以) 在pos后插 然后交换值///////////////void InsertNotHead(PNode pos, DataType data){PNode newnode = NULL;//?????????if(pos == NULL)return;newnode = BuyNode(pos->data);if(newnode)//必须判断节点是否申请成功{newnode->next = pos->next;    pos->next = newnode;pos->data = data;}} void Remove(PNode pHead, DataType data)//删除值为data的元素,直接调用Erase函数(传引用)与Find函数(不传引用){assert(pHead);Erase(&pHead, Find(pHead, data));}void RemoveAll(PNode* pHead, DataType data)//删除所有值为data的元素!!!!!!!!!!!!!!!!!!!!!有问题{PNode pcur = NULL;PNode pre = NULL;assert(pHead);//链表是否存在pre = *pHead;//定义两个指针 一个指向第一个节点pcur = pre->next;//指向第二个节点while(pcur)//遍历一遍单链表{if(pcur->data == data)//若pcur指向的节点值为data{pre->next = pcur->next;free(pcur);//释放pcur//pcur = pre;//让pcur指向前一个pcur = pre->next;}else{pcur = pcur->next;}}if((*pHead)->data == data)//如果头节点值为data的情况{pcur = *pHead;*pHead = (*pHead)->next;free(pcur);}}size_t Size(PNode pHead)//链表中元素个数{PNode pcur = NULL;int count = 0;assert(pHead);pcur = pHead;while(pcur){count++;pcur = pcur->next;}return count;}//PNode Front(PNode pHead)//{//assert(pHead);//return pHead;//}PNode Back(PNode pHead){PNode pcur = pHead;if(NULL == pHead)          return NULL;while(pcur->next){pcur = pcur->next;}return pcur;}//int Empty(PNode pHead);//////////////////////////////////////面试题//////////约瑟夫环/////////////////////////////////////////////PNode JosephCircle(PNode pHead, size_t M){PNode pCur = pHead;PNode pTemp = NULL;if(pHead == NULL)return NULL;while(pCur->next != pCur){size_t count = M;while(--count){pCur = pCur->next;}pTemp = pCur->next;pCur->data = pTemp->data;pCur->next = pTemp->next;free(pTemp);}return pCur;}//////////////////////////////////////////////测试////////////////////////////////////////////void FunTest4(){PNode pHead, pos;int count = 0;InitList(&pHead);PushBack(&pHead, 1);PushBack(&pHead, 2);PushBack(&pHead, 3);PushBack(&pHead, 4);PushBack(&pHead, 5);//Erase(&pHead, Find(pHead, 3));//Remove(pHead, 2);//RemoveAll(&pHead, 2);///////////有问题啊/////////////////////////////////////////////约瑟夫环//////////////////////////////////////pos = Back(pHead);//构环pos->next = pHead;//构环pHead = JosephCircle(pHead, 3);pHead->next = NULL;PrintList(pHead);//count = Size(pHead);//printf("%d\n",count);}void FunTest(){PNode pHead;InitList(&pHead);PushBack(&pHead, 1);PushBack(&pHead, 2);PushBack(&pHead, 3);PushBack(&pHead, 4);PrintList(pHead);PushFront(&pHead, 5);PrintList(pHead);PrintTail2Head(pHead);PopBack(&pHead);PrintList(pHead);PopBack(&pHead);PopBack(&pHead);PrintList(pHead);PopBack(&pHead);PrintList(pHead);PopBack(&pHead);PrintList(pHead);}void FunTest1(){PNode pHead;InitList(&pHead);PushFront(&pHead, 1);PushFront(&pHead, 2);PushFront(&pHead, 3);PushFront(&pHead, 4);PrintList(pHead);PopFront(&pHead);PrintList(pHead);PrintTail2Head(pHead);}void FunTest2(){PNode pHead, pos;InitList(&pHead);PushBack(&pHead, 1);PushBack(&pHead, 2);PushBack(&pHead, 3);PushBack(&pHead, 4);pos = Find(pHead, 2);Insert(pos,5);PrintList(pHead);Erase(&pHead, Find(pHead, 5));PrintList(pHead);Erase(&pHead, Find(pHead, 1));PrintList(pHead);DelNotTail(Find(pHead, 2));///只能删除非尾节点PrintList(pHead);}void FunTest3(){PNode pHead;InitList(&pHead);PushBack(&pHead, 1);PushBack(&pHead, 2);PushBack(&pHead, 3);PushBack(&pHead, 4);PrintList(pHead);InsertNotHead(Find(pHead, 2),5);PrintList(pHead);}int main(){FunTest4();system("pause");return 0;}


0 0
原创粉丝点击