c语言实现单链表&二级指针在单链表的应用

c语言实现单链表

用C语言实现链表的头插,头删,尾插,尾删,查找节点,任意节点插入,和任意节点删除等功能
此代码运用的是二级指针实现单链表,所以在写代码时要注意参数类型。

关于二级指针和一级指针:

一级指针变量指向的内容是普通变量的值,二级指针变量指向的内容是一级指针变量的地址。
当你想对一个地址做修改的时候,就要用到二级指针。

完整代码

#define __CRT_SECURE_NO_WARNRINGS 1
#include "slist.h"

//初始化链表
void InitLinkList(ListNode** ppList){
    assert(ppList);
    *ppList = NULL;
}
//打印链表
void PrintList(ListNode* pList){
    ListNode* cur = pList;
    while (cur){
        printf("%d ", cur->data);
            cur= cur->next;
    }
    printf("\n");
    return;
}
//申请一个新节点
ListNode* Buynewnode(DataType x){
    ListNode* newNode = NULL;
    newNode = (ListNode*)malloc(sizeof(ListNode));//开辟新节点,强制类型转换
    if (newNode == NULL){
        printf("out of memory \n");//溢出
    }
    else{
        newNode->data = x;
        newNode->next = NULL;
    }
    return newNode;
}
//尾插
void PushBack(ListNode** ppList, DataType x){
    assert(ppList);
    if (*ppList == NULL){
        *ppList = Buynewnode(x);
    }
    else{
        ListNode* ppcur = NULL;
        ppcur = *ppList;
        while (ppcur->next)
        {
            ppcur = ppcur->next;
        }
        ppcur->next = Buynewnode(x);
    }
}
//尾删
void PopBack(ListNode** ppList){
    assert(ppList);
    ListNode* cur = *ppList;
    if (cur == NULL){
        return ;
    }
    if (cur->next==NULL){
        free(cur);
        cur = NULL;
    }
    else{
        while (cur->next->next){
            cur = cur->next;
        }
        free(cur->next);
        cur->next = NULL;
    }
}
//头插
void PushFront(ListNode** ppList, DataType x){
    assert(ppList);
    ListNode* pFirst=NULL;
    if (*ppList==NULL){
        *ppList = Buynewnode(x);
    }
    else{
        pFirst = Buynewnode(x);
        pFirst->next = *ppList;
        *ppList = pFirst;
        }
}
//头删
void PopFront(ListNode** ppList){
    assert(ppList);
    if (*ppList == NULL){
        return;
    }
    else{
        ListNode* cur = *ppList;
        *ppList = (*ppList)->next;
        free(cur);
        cur = NULL;
    }

}
//查找表中元素x
ListNode* Find(ListNode* pList, DataType x){
    assert(pList);
    ListNode* cur = pList;
    //if (cur == NULL){
    //  return ;
    //}
    while (cur){
        if (cur->data == x)
            break;
        cur = cur->next;
        }
    return cur;
}

// 在pos的前面插入一个节点x 
void Insert(ListNode** ppList, ListNode* pos, DataType x){
    assert(ppList);
    assert(pos);
    DataType tmp=0;
    ListNode* newnode = Buynewnode(x);
    if (*ppList == NULL){
        PushBack(ppList, x);
    }
    else if (pos == NULL){
        return;
    }
    else{
        newnode->next =pos->next;
        pos->next = newnode;
        tmp = pos->data;
        pos->data = newnode->data;
        newnode->data = tmp;
    }
}
//删除pos前一位置节点
void Erase(ListNode** ppList, ListNode* pos){
    assert(ppList);
    assert(pos);
    ListNode* cur = *ppList;
    if (cur == NULL){
        return;
    }
    else{
        while (cur->next!=pos&&cur){
            cur = cur->next;
        }
        cur->next = pos->next;
        free(pos);
        pos = NULL;
    }
}

测试函数

#include "slist.h"
//测试

void test1()
{
    ListNode *list;
    InitLinkList(&list);
    printf("插入数据\n");
    PushBack(&list, 1);
    PushBack(&list, 2);
    PushBack(&list, 3);
    PushBack(&list, 4);
    PushBack(&list, 5);
    PushBack(&list, 6);
    PrintList(list);
    printf("从尾部删除数据后\n");
    PopBack(&list);
    PopBack(&list);
    PrintList(list);
    ListNode* _find;
    _find=Find(list, 2);
    printf("找到节点pos:%d\n", _find->data);
    ListNode* pos = _find;
    printf("在pos前插入节点:\n");
    Insert(&list,pos, 7);
    PrintList(list);
    printf("删除pos前节点:\n");
    Erase(&list, pos);
    PrintList(list);
}
void test2()
{
    ListNode* List;
    InitLinkList(&List);
    printf("头插数据\n");
    PushFront(&List, 1);
    PushFront(&List, 2);
    PushFront(&List, 3);
    PushFront(&List, 4);
    PrintList(List);
    printf("头删数据后");
    PopFront(&List);
    PopFront(&List);
    PopFront(&List);
    PopFront(&List);
    PrintList(List);

}
int main()
{

    test1();
    //test2();
    system("pause");
    return 0;
}

头文件

#define __CRT_SECURE_NO_WARNRINGS 1
#ifndef __SLIST_H__
#define __SLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int DataType;
typedef struct ListNode
{
    DataType data;
    struct ListNode* next;
}ListNode;

void InitLinkList(ListNode** ppList);
void PrintList(ListNode* pList);
ListNode* Buynewnode(DataType x);
void PushBack(ListNode** ppList, DataType x);
void PopBack(ListNode** ppList);
void PushFront(ListNode** ppList, DataType x);
void PopFront(ListNode** ppList);
ListNode* Find(ListNode* pList, DataType x);

// 在pos的前面插入一个节点x 
void Insert(ListNode** ppList, ListNode* pos, DataType x);
void Erase(ListNode** ppList, ListNode* pos);

#endif //__SLIST_H__

测试结果:

test1:

这里写图片描述

test2:

这里写图片描述

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值