C语言实现单链表
2017-04-12 18:08
183 查看
#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的next pos->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; }
相关文章推荐
- C语言单链表的建立,查找,添加,删除,修改功能实现
- 单链表操作演示----C语言实现
- 数据结构C语言之单链表简单实现
- 数据结构中单链表的实现+单链表的C语言实现源代码
- 单链表的C语言算法实现
- 顺序表的链式结构中用C语言实现单链表的交并差运算
- C语言实现有序单链表的插入
- 二、数据结构基础之单链表C语言实现
- 数据结构C语言单链表的实现和几点注意的问题
- C语言实现单链表的逆置
- C语言实现简单单链表
- 链表的C语言实现之单链表的实现
- C语言又一个单链表的实现
- 链表的C语言实现之单链表的实现
- c语言实现单链表的操作:创建,删除,插入,反转, 排序等
- 链表的C语言实现之单链表的实现
- C语言实现单链表的各种操作
- C语言实现单链表
- 自己编的C语言单链表的实现
- C语言实现单链表的逆置