代码实现链表的操作函数
1.首先是尾插 ,要实现尾插,首先的先有一个链表,并且为空。
即先构造一个链表,并且进行初始化。
[html] view plain copy
- //构造链表
 - typedef int DataType;
 - typedef struct SListNode {
 - DataType data;
 - struct SListNode *pNext;
 - } SListNode;
 - // 初始化
 - void SListInit(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - *ppFirst = NULL;
 - }
 - 进行尾插前,我们的在构造一个新链表,用来存放尾插后形成的新链表。
 - SListNode * CreateNewNode(int data)
 - {
 - SListNode *pNewNode = (SListNode *)malloc(sizeof(SListNode));
 - assert(pNewNode);
 - pNewNode->data = data;
 - pNewNode->pNext = NULL;
 - return pNewNode;
 - }
 - 下面进行尾插
 - void PushBack(SListNode **ppFirst, DataType data)
 - {
 - assert(ppFirst != NULL);
 - SListNode *pNewNode = CreateNewNode(data);
 - if (*ppFirst == NULL) {
 - *ppFirst = pNewNode;
 - return;
 - }
 - SListNode *pNode;
 - pNode = *ppFirst;
 - while (pNode->pNext != NULL) {
 - pNode = pNode->pNext;
 - }
 - // pNode 就是倒数第一个
 - pNode->pNext = pNewNode;
 - }
 - 再加上打印函数与测试函数,main函数。
 - void Print(SListNode *pFirst)
 - {
 - SListNode *pNode;
 - for (pNode = pFirst; pNode; pNode = pNode->pNext) {
 - printf("%d -> ", pNode->data);
 - }
 - printf("NULLn");
 - }
 - //测试函数
 - void TestSList()
 - {
 - SListNode *pFirst;
 - SListInit(&pFirst);
 - assert(pFirst == NULL);
 - PushBack(&pFirst, 1);
 - assert(pFirst != NULL);
 - Print(pFirst);
 - PushBack(&pFirst, 2);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 4);
 - Print(pFirst);
 - }
 - //main函数
 - #include"SList.h"
 - int main(){
 - TestSList();
 - system("pause");
 - }
 - 效果如下
 
    
2.头插
[html] view plain copy
- void PushFront(SListNode **ppFirst, DataType data)
 - {assert(ppFirst != NULL);
 - SListNode *pNewNode = CreateNewNode(data);
 - pNewNode->pNext = *ppFirst;
 - *ppFirst = pNewNode;
 - }
 - 测试函数如下:
 - PushFront(&pFirst, 5);
 - PushFront(&pFirst, 8);
 - Print(pFirst);
 
    
3.按下标插入(令给定下标是pos,pos一定存在)
[html] view plain copy
- void Insert(SListNode **ppFirst, SListNode *pPos, DataType data)
 - {
 - assert(ppFirst != NULL);
 - SListNode *pNode;
 - pNode = *ppFirst;
 - // pPos 是第一个结点地址
 - if (pPos == *ppFirst) {
 - PushFront(ppFirst, data);
 - return;
 - }
 - while (pNode->pNext != pPos){
 - pNode = pNode->pNext;
 - }
 - SListNode *pNewNode = CreateNewNode(data);
 - pNode->pNext = pNewNode;
 - pNewNode->pNext = pPos;
 - }
 - 进行按给定位置插入 需确定pos位置,需定义find函数
 - //find
 - SListNode * Find(SListNode *pFirst, DataType data)
 - {
 - SListNode *pNode;
 - for (pNode = pFirst; pNode; pNode = pNode->pNext) {
 - if (pNode->data == data) {
 - return pNode;
 - }
 - }
 - return NULL;
 - }
 - 测试代码如下:
 - SListNode *pFound = Find(pFirst, 3);
 - if (pFound == NULL) {
 - printf("没有找到n");
 - }
 - else {
 - printf("%dn", pFound->data);
 - Insert(&pFirst, pFound, 100);
 - }
 - Print(pFirst);
 - 效果如下:
 
    
二、删除
1.头删
[html] view plain copy
- void PopFront(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - assert(*ppFirst != NULL);
 - SListNode *pOldFirst = *ppFirst;
 - *ppFirst = (*ppFirst)->pNext;
 - free(pOldFirst);
 - }
 - 测试代码如下:
 - PopFront(&pFirst);
 - Print(pFirst);
 - 效果如下:
 
    

2.尾删
[html] view plain copy
- void PopBack(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - assert(*ppFirst != NULL);
 - if ((*ppFirst)->pNext == NULL) {
 - free(*ppFirst);
 - *ppFirst = NULL;
 - return;
 - }
 - SListNode *pNode = *ppFirst;
 - while (pNode->pNext->pNext != NULL)
 - {
 - pNode = pNode->pNext;
 - }
 - free(pNode->pNext);
 - pNode->pNext = NULL;
 - }
 - 测试函数如下:
 - PopBack(&pFirst);
 - Print(pFirst);
 - 效果如下:
 
    
3.按位置删除(根据结点地址删除,结点肯定在链表里,令节点位置为pPos)
[html] view plain copy
- void Erase(SListNode **ppFirst, SListNode *pPos)
 - {
 - assert(ppFirst != NULL);
 - assert(*ppFirst != NULL);
 - if (*ppFirst == pPos) {
 - PopFront(ppFirst);
 - return;
 - }
 - SListNode *pCur;
 - for (pCur = *ppFirst; pCur->pNext != pPos; pCur = pCur->pNext) {
 - }
 - // pCur 就是 pPos的前一个
 - pCur->pNext = pPos->pNext;
 - free(pPos);
 - }
 - 测试函数如下:
 - SListNode *pFound = Find(pFirst, 1);
 - { if (pFound == NULL) {
 - printf("没有找到n");
 - }
 - else {
 - printf("%dn", pFound->data);
 - Erase(&pFirst, pFound);
 - }
 - SListDestroy(&pFirst);
 - }
 - 运行效果如下
 
4.按值删除(根据数据去删除,删除遇到的第一个结点)
[html] view plain copy
- void Remove(SListNode **ppFirst, DataType data)
 - {
 - SListNode *pFound = Find(*ppFirst, data);
 - if (pFound != NULL) {
 - Erase(ppFirst, pFound);
 - }
 - }
 - 测试函数如下:
 - void TestRemove()
 - {
 - SListNode *pFirst;
 - SListInit(&pFirst);
 - PushBack(&pFirst, 4);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 1);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 5);
 - PushBack(&pFirst, 3);
 - Print(pFirst);
 - Remove(&pFirst, 3);
 - Print(pFirst);
 - 运行效果如图
 
5.按值删除( 根据数据去删除,删除遇到的所有结点)
[html] view plain copy
- void RemoveAll(SListNode **ppFirst, DataType data)
 - {
 - SListNode *pNode = *ppFirst;
 - SListNode *pNext;
 - while (pNode->pNext) {
 - if (pNode->pNext->data == data) {
 - pNext = pNode->pNext;
 - pNode->pNext = pNode->pNext->pNext;
 - free(pNext);
 - }
 - else {
 - pNode = pNode->pNext;
 - }
 - }
 - if ((*ppFirst)->data == data) {
 - PopFront(ppFirst);
 - }
 - }
 - 测试函数如下:
 - RemoveAll(&pFirst, 3);
 - Print(pFirst);
 - 测试效果如下
 
    
源代码如下:
[html] view plain copy
- Hello.h
 - #pragma once
 - #include <stdlib.h>
 - #include <assert.h>
 - #include <stdio.h>
 - typedef int DataType;
 - typedef struct SListNode {
 - DataType data;
 - struct SListNode *pNext;
 - } SListNode;
 - // 初始化
 - void SListInit(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - *ppFirst = NULL;
 - }
 - SListNode * CreateNewNode(int data)
 - {
 - SListNode *pNewNode = (SListNode *)malloc(sizeof(SListNode));
 - assert(pNewNode);
 - pNewNode->data = data;
 - pNewNode->pNext = NULL;
 - return pNewNode;
 - }
 - //打印函数
 - void Print(SListNode *pFirst)
 - {
 - SListNode *pNode;
 - for (pNode = pFirst; pNode; pNode = pNode->pNext) {
 - printf("%d -> ", pNode->data);
 - }
 - printf("NULLn");
 - }
 - // 销毁
 - void SListDestroy(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - SListNode *pNode, *pNext;
 - pNode = *ppFirst;
 - while (pNode != NULL) {
 - pNext = pNode->pNext;
 - free(pNode);
 - pNode = pNext;
 - }
 - *ppFirst = NULL;
 - }
 - // 查找,返回遇到的第一个
 - // 如果找到了,返回结点地址
 - // 否则返回 NULL
 - SListNode * Find(SListNode *pFirst, DataType data)
 - {
 - SListNode *pNode;
 - for (pNode = pFirst; pNode; pNode = pNode->pNext) {
 - if (pNode->data == data) {
 - return pNode;
 - }
 - }
 - return NULL;
 - }
 - // 增删改查
 - // 尾插
 - void PushBack(SListNode **ppFirst, DataType data)
 - {
 - assert(ppFirst != NULL);
 - SListNode *pNewNode = CreateNewNode(data);
 - if (*ppFirst == NULL) {
 - *ppFirst = pNewNode;
 - return;
 - }
 - SListNode *pNode;
 - pNode = *ppFirst;
 - while (pNode->pNext != NULL) {
 - pNode = pNode->pNext;
 - }
 - // pNode 就是倒数第一个
 - pNode->pNext = pNewNode;
 - }
 - /*
 - // 头插
 - void PushFront(SListNode **ppFirst, DataType data)
 - {
 - assert(ppFirst != NULL);
 - SListNode *pNewNode = CreateNewNode(data);
 - pNewNode->pNext = *ppFirst;
 - *ppFirst = pNewNode;
 - }
 - // 插入到给定结点 pPos 前,pPos 肯定在链表里
 - void Insert(SListNode **ppFirst, SListNode *pPos, DataType data)
 - {
 - assert(ppFirst != NULL);
 - SListNode *pNode;
 - pNode = *ppFirst;
 - // pPos 是第一个结点地址
 - if (pPos == *ppFirst) {
 - PushFront(ppFirst, data);
 - return;
 - }
 - while (pNode->pNext != pPos){
 - pNode = pNode->pNext;
 - }
 - SListNode *pNewNode = CreateNewNode(data);
 - pNode->pNext = pNewNode;
 - pNewNode->pNext = pPos;
 - }
 - */
 - // 头删
 - void PopFront(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - assert(*ppFirst != NULL);
 - SListNode *pOldFirst = *ppFirst;
 - *ppFirst = (*ppFirst)->pNext;
 - free(pOldFirst);
 - }
 - // 尾删
 - void PopBack(SListNode **ppFirst)
 - {
 - assert(ppFirst != NULL);
 - assert(*ppFirst != NULL);
 - if ((*ppFirst)->pNext == NULL) {
 - free(*ppFirst);
 - *ppFirst = NULL;
 - return;
 - }
 - SListNode *pNode = *ppFirst;
 - while (pNode->pNext->pNext != NULL)
 - {
 - pNode = pNode->pNext;
 - }
 - free(pNode->pNext);
 - pNode->pNext = NULL;
 - }
 - // 根据结点地址删除,结点肯定在链表里
 - void Erase(SListNode **ppFirst, SListNode *pPos)
 - {
 - assert(ppFirst != NULL);
 - assert(*ppFirst != NULL);
 - if (*ppFirst == pPos) {
 - PopFront(ppFirst);
 - return;
 - }
 - SListNode *pCur;
 - for (pCur = *ppFirst; pCur->pNext != pPos; pCur = pCur->pNext) {
 - }
 - // pCur 就是 pPos的前一个
 - pCur->pNext = pPos->pNext;
 - free(pPos);
 - }
 - /*
 - void TestSList()
 - {
 - SListNode *pFirst;
 - SListInit(&pFirst);
 - assert(pFirst == NULL);
 - PushBack(&pFirst, 1);
 - assert(pFirst != NULL);
 - Print(pFirst);
 - PushBack(&pFirst, 1);
 - PushBack(&pFirst, 2);
 - PushBack(&pFirst, 3);
 - Print(pFirst);
 - PushFront(&pFirst, 5);
 - PushFront(&pFirst, 8);
 - Print(pFirst);
 - SListNode *pFound = Find(pFirst, 3);
 - if (pFound == NULL) {
 - printf("没有找到n");
 - }
 - else {
 - printf("%dn", pFound->data);
 - Insert(&pFirst, pFound, 100);
 - }
 - Print(pFirst);
 - PopFront(&pFirst);
 - Print(pFirst);
 - PopBack(&pFirst);
 - Print(pFirst);
 - SListNode *pFound = Find(pFirst, 9);
 - { if (pFound == NULL) {
 - printf("没有找到n");
 - }
 - else {
 - printf("%dn", pFound->data);
 - Erase(&pFirst, pFound);
 - }
 - SListDestroy(&pFirst);
 - }
 - }
 - */
 - // 根据数据去删除,删除遇到的第一个结点
 - void Remove(SListNode **ppFirst, DataType data)
 - {
 - SListNode *pFound = Find(*ppFirst, data);
 - if (pFound != NULL) {
 - Erase(ppFirst, pFound);
 - }
 - }
 - // 根据数据去删除,删除遇到的所有结点
 - void RemoveAll(SListNode **ppFirst, DataType data)
 - {
 - SListNode *pNode = *ppFirst;
 - SListNode *pNext;
 - while (pNode->pNext) {
 - if (pNode->pNext->data == data) {
 - pNext = pNode->pNext;
 - pNode->pNext = pNode->pNext->pNext;
 - free(pNext);
 - }
 - else {
 - pNode = pNode->pNext;
 - }
 - }
 - if ((*ppFirst)->data == data) {
 - PopFront(ppFirst);
 - }
 - }
 - void TestRemove()
 - {
 - SListNode *pFirst;
 - SListInit(&pFirst);
 - PushBack(&pFirst, 4);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 1);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 3);
 - PushBack(&pFirst, 5);
 - PushBack(&pFirst, 3);
 - Print(pFirst);
 - Remove(&pFirst, 3);
 - Print(pFirst);
 - RemoveAll(&pFirst, 3);
 - Print(pFirst);
 - }
 
[html] view plain copy
- main.c
 - #include"Hello.h"
 - int main(){
 - TestRemove();
 - //TestSList();
 - system("pause");
 - }
 
到此,单链表的基本功能差不多都实现了。
    








