ListNode.h
#define _CRT_SECURE_NO_WARNING 1 #pragma once #include <stdio.h> #include <assert.h> #include <stdlib.h> typedef int DataType; typedef struct ListNode { struct ListNode* _pNext; //指向链表中下一个结点 DataType data; //当前节点中保存的元素 }Node,*PNode; void ListNodeInit(PNode* pHead); //链表的初始化 void ListNodePushBack(PNode* pHead,DataType data);//链表的尾插 void ListNodePopBack(PNode* pHead);//尾删 void ListNodePushFront(PNode* pHead,DataType data);//链表的头插 void ListNodePopFront(PNode* pHead);//链表的头删 //在链表中查找值为data的元素,找到后返回值为data的结点 PNode ListNodeFind(PNode pHead,DataType data); //在pos位置插入值为data的结点 void ListNodeInsert(PNode* pHead,PNode pos,DataType data); //删除pos位置的结点 void ListNodeErase(PNode* pHead,PNode pos); //获取链表中值为data的结点 int ListNodeSize(PNode pHead); //判断链表是否为空 int ListNodeEmpty(PNode pHead); //销毁链表 void ListNodeDestroy(PNode* pHead); //打印链表 void ListNodePrint(PNode pHead);
ListNode.c
#define _CRT_SECURE_NO_WARNING 1 #include "ListNode.h" //单链表初始化 将链表头指针赋空 void ListNodeInit(PNode* pHead)//*pHead指向的是外部实参的地址 { assert(pHead);//断言链表是否存在 *pHead = NULL; } //创建新结点 PNode BuyNewNode(DataType data) { PNode NewNode = (PNode)malloc(sizeof(Node)); if(NULL == NewNode) { assert(0); return NULL; } NewNode->data = data; NewNode->_pNext = NULL; return NewNode; } //链表的尾插 void ListNodePushBack(PNode* pHead,DataType data) { PNode pCur = NULL; assert(pHead);//断言链表是否存在 if(NULL == *pHead) { *pHead = BuyNewNode(data);//如果为空就让链表头结点指向新节点 return; } pCur = *pHead; //找到最后一个结点 while(pCur ->_pNext) { pCur = pCur->_pNext; } pCur->_pNext = BuyNewNode(data); } //链表的尾删 void ListNodePopBack(PNode* pHead) { PNode pCur = *pHead; PNode pPre = *pHead; assert(pHead); if(NULL == *pHead) { printf("链表已空无法删除!!!\n"); return; } //1.只有一个结点 if(pCur->_pNext == NULL) { free(*pHead); *pHead = NULL; return; } //2.有多个结点 while(pCur->_pNext) { pPre = pCur;//每走一步保存一下前一个结点直到找到倒数第二个结点 pCur = pCur->_pNext; } free(pCur->_pNext); pPre->_pNext = NULL; } //链表的头插 void ListNodePushFront(PNode* pHead,DataType data) { PNode ptr = NULL; assert(pHead); //1.链表为空 if(NULL == *pHead) { *pHead = BuyNewNode(data); return; } //2.链表不为空 ptr = *pHead;//先保存第一个结点的地址 *pHead = BuyNewNode(data);//头指针指向新节点 (*pHead)->_pNext = ptr;//将新的头指针的_pNext指向原来的头指针ptr } //链表的头删 void ListNodePopFront(PNode* pHead) { PNode ptr = NULL; assert(pHead); if(NULL == *pHead) { printf("链表已空无法删除!!!\n"); return; } //1.只有一个结点 if( (*pHead)->_pNext == NULL) { free(*pHead); *pHead = NULL; return; } //2.有多个结点 ptr = *pHead;//保存头结点地址 *pHead = (*pHead)->_pNext;//头指针指向他后面的一个节点地址 free(ptr); } //在链表中查找值为data的元素,找到后返回值为data的结点 PNode ListNodeFind(PNode pHead,DataType data) { PNode pCur = pHead; if(NULL == pHead ) { printf("链表为空无法查找!!!\n"); return NULL; } while( (pCur) && (pCur->data !=data) )//pCur不为空且pCur中的值不是要查找data则进入循环 { pCur = pCur->_pNext; } //1.pCur遍历后仍为空证明链表中没有data if(NULL == pCur) { printf("链表中无data!!!\n"); return NULL; } else return pCur; } //在pos位置插入值为data的结点 void ListNodeInsert(PNode* pHead,PNode pos,DataType data) { PNode pCur = *pHead; assert(pHead); //1.链表为空 if(NULL == *pHead) { //1)若插入的位置和头结点地址不同,那么是非法的,插入失败 if(pos == *pHead) { *pHead = BuyNewNode(data); return; } else { printf("非法插入!!!\n"); return; } } //2.链表不为空 if(pos == *pHead) //1)插入位置与头结点地址相等 ListNodePushFront(pHead,data); else //2)插入位置不在头结点位置 { while( (pCur) && (pCur->_pNext != pos) ) { pCur = pCur->_pNext; } if(pCur == NULL) { printf("找不到该节点无法插入!!!\n"); return; } else { PNode NewNode = NULL; DataType tmp; NewNode = BuyNewNode(data); NewNode->_pNext = pos->_pNext; pos->_pNext = NewNode; tmp = pos->data; pos->data = data; NewNode->data = tmp; } } } //删除pos位置的结点 void ListNodeErase(PNode* pHead,PNode pos) { PNode pPre = *pHead; assert(pHead); if(NULL == pHead || NULL == pos) { printf("链表为空无法删除!!!\n"); printf("pos位置为空删除失败!!!\n"); return; } //1.只有一个结点 if( (*pHead)->_pNext == NULL) { if(*pHead == pos) { free(pos); *pHead = NULL; return; } else return; } //2.多个结点 if(*pHead == pos)//1)pos位置是头结点 { *pHead = (*pHead)->_pNext; free(pos); return; } //2)pos位置不是头结点 while( (pPre) && (pPre->_pNext !=pos) && (pos) ) { pPre = pPre->_pNext; } if( (pPre == NULL) || (pos == NULL) ) return; else { pPre->_pNext = pos->_pNext; free(pos); } } //获取链表中值为data的结点 int ListNodeSize(PNode pHead) { int count = 0; while(pHead) { pHead = pHead->_pNext; count++; } return count; } //判断链表是否为空 int ListNodeEmpty(PNode pHead) { if(pHead) return 1; return 0; } //销毁链表 void ListNodeDestroy(PNode* pHead) { PNode pNext = *pHead; PNode pCur = *pHead; assert(pHead); if(NULL == *pHead) { printf("链表为空无法销毁!!!\n"); return; } while(pCur) { pNext = pCur->_pNext; free(pCur); pCur = pNext; } *pHead = NULL; } //打印链表 void ListNodePrint(PNode pHead) { PNode ptr = pHead; if(NULL == pHead) return; while(ptr) { printf("%d--->", ptr->data); ptr = ptr->_pNext; } printf("NULL\n"); }
test.c
#define _CRT_SECURE_NO_WARNING 1 #include "ListNode.h" int main() { Node List; PNode pHead = &List; ListNodeInit(&pHead);// 链表的初始化 ListNodeEmpty(pHead); ListNodeInsert(&pHead,pHead,32); ListNodePrint(pHead); ListNodePushFront(&pHead,1); ListNodePrint(pHead); ListNodePushBack(&pHead, 1);//尾插 ListNodePushBack(&pHead, 2); ListNodePushBack(&pHead, 6); ListNodePushBack(&pHead, 3); ListNodePushBack(&pHead, 6); ListNodePushBack(&pHead, 4); ListNodePushBack(&pHead, 5); ListNodePrint(pHead); ListNodePopBack(&pHead);//链表的尾删 ListNodePrint(pHead); ListNodePopFront(&pHead);//链表的头删 ListNodePrint(pHead); ListNodeFind(pHead,6);//查找值为data的元素 ListNodePrint(pHead); ListNodeInsert(&pHead,pHead->_pNext->_pNext,28); ListNodePrint(pHead); ListNodeErase(&pHead,pHead->_pNext); ListNodePrint(pHead); ListNodeSize(pHead); ListNodePrint(pHead); ListNodeDestroy(&pHead); ListNodePrint(pHead); return 0; }