标签:单链表
//头文件 #pragma once #include <stdio.h> #include <assert.h> #include <malloc.h> #include <stdlib.h> typedef int DateType; typedef struct LinkNode { DateType _data; struct LinkNode* _next; } LinkNode; void PrintList(LinkNode* pHead) //打印 { LinkNode* begin = pHead; while (begin != NULL) { printf("%d->", begin->_data); begin = begin->_next; //这里要注意,不要写反了:begin->_next=begin; } printf("NULL\n"); } LinkNode* BuyNode(DateType x) //初始化节点 { LinkNode* tmp = (LinkNode*)malloc(sizeof(LinkNode)); if (tmp == NULL) { printf("malloc faile"); exit(-1); } tmp->_next = NULL; tmp->_data = x; return tmp; } void PushFront(LinkNode*& pHead, DateType x)//头插 { //空链表 if (pHead == NULL) //证明是空链表,需要开辟节点 { pHead = BuyNode(x); } else { LinkNode* nowNode = BuyNode(x); nowNode->_next = pHead; //把头指针的节点给我的_next,我就指向你,实现了前叉 pHead = nowNode; } } void PopFront(LinkNode*& pHead)//头删,有三种情况: { if (pHead == NULL) // 空 { return; } else if (pHead->_next == NULL) // 一个节点 { free(pHead); pHead = NULL; } else // 两个及以上节点 { LinkNode*del = pHead; //先保存后面的节点,再来把前面的删了 pHead = pHead->_next; free(del); } } void PushBack(LinkNode*& pHead, DateType x)//尾插 { //空 if (pHead == NULL) //证明是空链表,需要开辟节点 { pHead = BuyNode(x); } else { LinkNode* tail = pHead; while (tail->_next != NULL) //注意循环的条件不能写成 tail != NULL { tail = tail->_next; } tail->_next = BuyNode(x); } } void PopBack(LinkNode*& pHead) //尾删 { if (pHead == NULL) //没有节点 { return; } else if (pHead->_next == NULL) //一个节点 { free(pHead); pHead = NULL; } else // 两个节点及以上 { //LinkNode* cur = pHead; //这里需要两个指针,一前一后,因为删除后一个节点需要前一个节点 //LinkNode* prev = NULL; //while (cur->_next != NULL) //注意循环的条件不能写成 cur != NULL //{ // prev = cur; // cur = cur->_next; //} //prev->_next = NULL; //free(cur); //或者下面这种方法: LinkNode* prevTail = pHead; while (prevTail->_next->_next!=NULL) { prevTail = prevTail->_next; } free(prevTail->_next); prevTail->_next = NULL; } } LinkNode* Find(LinkNode* pHead,DateType x)// 找一个数 { LinkNode* cur = pHead; while (cur) { if (cur->_data == x) { return cur; } cur = cur->_next; } return NULL; } void Insert(LinkNode* pos, DateType x) //任意位置插入 { LinkNode* tmp = BuyNode(x); assert(pos); tmp->_next = pos->_next; //这边要特别注意, pos->_next = tmp; /*LinkNode* tmp = BuyNode(x); LinkNode* next = NULL; assert(pos); next = pos->_next; pos->_next = tmp; tmp->_next = next;*/ } void Erase(LinkNode*& pHead,LinkNode* pos) //删除一个节点 { assert(pos); //pos是头结点 //pos是中间节点 if (pHead == pos) //只有一个节点 { LinkNode* del = pos; pHead = pHead->_next; free(del); } else //有多个节点情况 { //pos不在链表中的情况 LinkNode* prev = pHead; while (prev && prev->_next != pos) { prev = prev->_next; } if (prev) { prev->_next = pos->_next; free(pos); } } } LinkNode* Reverse(LinkNode*& pHead) //逆置链表 { LinkNode* cur = pHead; LinkNode* newHead = NULL; LinkNode* tmp; while (cur) { tmp = cur; cur = cur->_next; tmp->_next = newHead; newHead = tmp; } return newHead; } LinkNode* FindMidNode(LinkNode* pHead) //找中间节点 { LinkNode* first = pHead; LinkNode* second = pHead; while (second->_next != NULL) { if (second->_next->_next == NULL) { return first; break; } else { first = first->_next; second = second->_next->_next; } } return first; } LinkNode* FindNodeFromBack(LinkNode* pHead, int x)//找倒数第x个节点 { int i = 0; LinkNode*first = pHead; LinkNode*second = pHead; while (first && (i < x)) { first = first->_next; i++; } if (i < x) { return NULL; } while (first) { first = first->_next; second = second->_next; } return second; } //删除一个无头单链表的非尾节点 int GetListLength(LinkNode* pHead) //获取链表长度 { int count = 0; LinkNode* begin = pHead; while (begin) { count++; begin = begin->_next; } return count; } void DestoryList(LinkNode*& pHead) //删除所有节点 { LinkNode* begin = pHead; while (begin) { LinkNode* del = begin; begin = begin->_next; free(del); } pHead = NULL; } //源文件 #include "Slist.h" void Test1()//头操作 { LinkNode* pHead = NULL; //头指针 PushFront(pHead, 1); PushFront(pHead, 2); PushFront(pHead, 3); PushFront(pHead, 4); PrintList(pHead);//打印 PopFront(pHead); PopFront(pHead); PopFront(pHead); PopFront(pHead); PopFront(pHead); PrintList(pHead);//打印 } void Test2()//尾操作 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PrintList(pHead);//打印 PopBack(pHead); PopBack(pHead); PopBack(pHead); PopBack(pHead); PopBack(pHead); PrintList(pHead);//打印 } void Test3()//获取链表长度 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PrintList(pHead);//打印 int ret = GetListLength(pHead); printf("%d\n",ret); } void Test4()//删除整个链表 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PrintList(pHead);//打印 DestoryList(pHead); PrintList(pHead); } void Test5()//找一个数,找到这个数后插入一个数 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PrintList(pHead); LinkNode* ret = Find(pHead, 2); printf("%d\n", ret->_data); Insert(ret, 8); //找到2后,在2后面插个8 PrintList(pHead); ret = Find(pHead, 7); //7不存在 printf("ret=NULL:%p\n", ret); } void Test6() //删除指定位置的数 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PrintList(pHead); LinkNode* ret = Find(pHead, 2); Erase(pHead,ret); //找到2后,把2删除 PrintList(pHead); } void Test7() //找中间节点 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PushBack(pHead, 5); PushBack(pHead, 6); //PushBack(pHead, 7); PrintList(pHead); LinkNode* ret=Reverse(pHead); PrintList(ret); /*LinkNode*ret=FindMidNode(pHead); printf("%d\n", ret->_data);*/ } void Test8() //返回倒数第k个节点 { LinkNode* pHead = NULL; PushBack(pHead, 1); PushBack(pHead, 2); PushBack(pHead, 3); PushBack(pHead, 4); PushBack(pHead, 5); PushBack(pHead, 6); PrintList(pHead); LinkNode* ret = FindNodeFromBack(pHead,3); printf("%d\n", ret->_data); /*LinkNode*ret=FindMidNode(pHead); printf("%d\n", ret->_data);*/ } int main() { //Test1(); //Test2(); //Test3(); //Test4(); //Test5(); //Test6(); //Test7(); Test8(); return 0; }
标签:单链表
原文地址:http://10706198.blog.51cto.com/10696198/1715578