单链表的基本操作

原创 2018年04月16日 15:25:09

单链基本操作的部分思维导图

这里写图片描述

代码

头文件.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int DataType;

typedef struct ListNode{
    struct ListNode *_pNext;
    DataType _data;
}Node,*PNode;


void ListNodeInit(PNode* PHead);    //初始化单链表
PNode BuyNode(DataType data);   //创建新节点
void ListPushBack(PNode* PHead, DataType data); //尾插
void ListPopBack(PNode* PHead); //  尾删
void ListPushFront(PNode* PHead, DataType data);    //头插
void ListPopFront(PNode* PHead);//头删
PNode ListFind(PNode PHead, DataType data); // 在链表中查找值为data的元素,找到后返回值为data的结点 
void ListInsert(PNode* pHead, PNode pos, DataType data);    // 在pos位置插入值为data的结点
void ListErase(PNode* pHead, PNode pos);    // 删除pos位置的结点
int ListEmpty(PNode pHead); //判断链表是否为空
int SListSize(PNode pHead); // 获取链表中值data的结点 
void SListDestroy(PNode* pHead);    // 销毁聊表


PNode FindNode(PNode PHead, int pos);   //查找已经存在的链表内是否存在第pos位结点
void ListPrint(PNode PHead);    //打印结点内容

功能模块

#include"Apr_14.h"

//初始化链表
void ListNodeInit(PNode* pHead)
{
    assert(pHead);
    *pHead =  NULL;
}

//申请节点
PNode BuyNode(DataType data)
{
    PNode NewNode = (PNode)malloc(sizeof(Node));    //sizeof(Node)  内部一定是结点的大小,而不是指针的大小

    if (NULL == NewNode)    //虽然几率很小,但是万一申请失败程序就会崩溃,所以记得加容错机制
    {
        assert(0);
        return NULL;
    }

    NewNode->_data = data;
    NewNode->_pNext = NULL;
    return NewNode;
}

//尾插
void ListPushBack(PNode* PHead, DataType data)
{
    assert(PHead);  //PHead内存的链表的地址,如果为空,则说明链表不存在

    if (NULL == *PHead) //检查链表是否为空
        *PHead = BuyNode(data);
    else
    {
        PNode pCur = *PHead;

        //找出最后一个结点
        //while(pCur)也是寻找最后一个结点的一种方法,不过要保存它的前一个结点
        while (pCur->_pNext)
        {
            pCur = pCur->_pNext;
        }
        pCur->_pNext = BuyNode(data);
    }
}

//尾删
void ListPopBack(PNode* PHead)
{
    PNode Del = NULL;   
    PNode prev = NULL;
    assert(PHead);

    if (NULL == *PHead) //链表为空,没有结点需要删除
    {
        return;
    }

    else if ((*PHead)->_pNext)
    {
        Del = *PHead;
        while (Del->_pNext)
        {
            prev = Del;
            Del = Del->_pNext;
        }
        free(Del);
        prev->_pNext = NULL;
    }
    else if (*PHead)
    {
        free((*PHead));
        *PHead = NULL;
    }
}

//头插
void ListPushFront(PNode* PHead, DataType  data)
{
    assert(PHead);

    PNode NewNode;
    if (NULL == *PHead)
    {
        NewNode = BuyNode(data);
        NewNode->_pNext = NULL;
        *PHead = NewNode;
    }
    else
    {
        NewNode = BuyNode(data);
        NewNode->_pNext = *PHead;
        *PHead = NewNode;
    }
}

//头删
void ListPopFront(PNode* PHead)
{
    PNode Del = (*PHead);
    PNode Pre = NULL;

    assert(PHead);

    if (NULL == PHead)
    {
        return;
    }

    if ((*PHead)->_pNext)
    {   
        *PHead = (*PHead)->_pNext;
        free(Del);
        Del = NULL;
    }
    else if (*PHead)
    {
        free(Del);
        *PHead = NULL;
    }
}

// 在链表中查找值为data的元素,找到后返回值为data的结点 
PNode ListFind(PNode PHead, DataType data)
{
    PNode PCur = NULL;
    assert(PHead);

    if (NULL == PHead)
        return NULL;

    PCur = PHead;

    while (PCur)
    {
        if (PCur->_data == data)
        {
            return PCur;
        }
        PCur = PCur->_pNext;
    }

    return NULL;
}

// 在pos位置插入值为data的结点
void ListInsert(PNode* PHead, PNode pos, DataType data)
{
    assert(PHead);

    if (NULL == (*PHead))   //  链表为空,自动头插
        ListPushFront(PHead, data);
    if (pos == NULL)    //插入位置为空,缺省为头插
        ListPushFront(PHead, data);
    else if (!pos->_pNext)  //插入位置为链表末尾
    {
        ListPushBack(PHead, data);  
    }
    else
    {
        PNode PCur = NULL;
        PNode NewNode = NULL;
        DataType tmp;

        NewNode = BuyNode(data);    
        NewNode->_pNext = pos->_pNext;
        pos->_pNext = NewNode;
        tmp = pos->_data;
        pos->_data = data;
        NewNode->_data = tmp;
    }

}

// 删除pos位置的结点
void ListErase(PNode* PHead, PNode pos)
{
    PNode Del = NULL;
    PNode PPre = NULL;
    assert(PHead);

    if (NULL == *PHead || NULL == pos)
        return;

    Del = *PHead;
    while (Del && Del != pos)
    {
        PPre = Del;
        Del = Del->_pNext;
    }
    if (Del->_pNext != NULL)
    {
        PPre->_pNext = Del->_pNext;
        free(Del);
        Del = NULL;
    }
    else
    {
        free(Del);
        PPre->_pNext = NULL;
    }
}

int ListEmpty(PNode pHead)
{
    if (NULL == pHead)
    {
        printf("链表为空\n");
        return 0;
    }
    else
    {
        return 1;
    }
}

// 销毁链表
void SListDestroy(PNode* PHead)
{
    PNode Des;
    assert(PHead);

    if (NULL == (PHead))
        return;

    Des = *PHead;
    while (Des)
    {
        Des = (*PHead)->_pNext;
        free(*PHead);
        if (Des)
            (*PHead) = Des;
    }
    *PHead = NULL;
}



//查找链表中是否存在第pos个结点
PNode FindNode(PNode PHead, int pos)
{
    PNode PCur = NULL;
    PNode PPre = NULL;
    if (NULL == PHead)
    {
        return NULL;
    }

    PCur = PHead;
    while (pos && PCur)
    {
        PPre = PCur;
        PCur = PCur->_pNext;
        pos--;
    }

    if (pos == 0)
        return PPre;
    else
        return NULL;
}


//打印
void ListPrint(PNode PHead)
{
    if (NULL == PHead)
        return;

    while (PHead)
    {
        printf("%d ", PHead->_data);
        PHead = PHead->_pNext;
    }
    printf("\n");
}

测试文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Apr_14.h"

void TestPushOrPop()
{
    PNode PHead;
    ListNodeInit(&PHead);
    ListPushBack(&PHead, 6);
    ListPushBack(&PHead, 9);
    ListPushBack(&PHead, 8);
    ListPrint(PHead);
    ListPopBack(&PHead);
    ListPushBack(&PHead, 11);
    ListPrint(PHead);
    ListPopBack(&PHead);
    ListPushFront(&PHead, 3);
    ListPrint(PHead);
    ListPopFront(&PHead);
    ListPrint(PHead);
}

void TestListFind()
{
    PNode PHead;
    PNode tmp = NULL;
    ListNodeInit(&PHead);
    ListPushBack(&PHead, 6);
    ListPrint(PHead);
    ListPushBack(&PHead, 9);
    ListPushBack(&PHead, 8);
    ListPushFront(&PHead, 3);
    ListPushFront(&PHead, 7);
    ListPushFront(&PHead, 1);
    ListPrint(PHead);
    tmp = ListFind(PHead, 9);
    if (tmp)
    {
        printf("%d\n", tmp->_data);
    }
    tmp = FindNode(PHead, 3);
    if (tmp)
    {
        printf("%d\n", tmp->_data);
    }
    ListInsert(&PHead, tmp, 13);
    ListPrint(PHead);
    tmp = NULL;
    ListInsert(&PHead, tmp, 0);
    ListPrint(PHead);
    tmp = FindNode(PHead, 6);
    ListErase(&PHead, tmp);
    ListPrint(PHead);
    tmp = FindNode(PHead, 7);
    ListErase(&PHead, tmp);
    ListPrint(PHead);
    SListDestroy(&PHead);
}

int main()
{
    TestPushOrPop();
    TestListFind();
    system("pause");
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zym1348010959/article/details/79961188

VB中获取逻辑磁盘的信息

我们在编程的时候有时会需要得到系统中逻辑磁盘的一些信息,如磁盘卷标、磁盘序列号、空间大小、剩余空间等,这些信息直接使用VB提供的函数显然是无法得到的。但是,借助于VB对WINDOWS API函数的支持...
  • jadedrip
  • jadedrip
  • 2000-11-08 22:20:00
  • 1038

单链表基本操作java实现

单链表基本操作 - java实现 1.单链表学习了好久,今天终于有时间写一下了,带头结点的单链表上的基本操作,Java实现。 (1) 先来个接口 public interface IList { ...
  • ping1632743560
  • ping1632743560
  • 2016-09-26 20:04:42
  • 396

c++学习笔记—单链表基本操作的实现

用c++语言实现的单链表基本操作,包括单链表的创建(包括头插法和尾插法建表)、结点的查找、删除、排序、打印输出、逆置、链表销毁等基本操作。 IDE:vs2013 具体实现代码如下: #includ...
  • xujian_2014
  • xujian_2014
  • 2015-01-14 21:13:09
  • 1397

单链表的基本操作c语言实现

#include #define false 0 #define ok 1//定义节点的结构 typedef struct node{ int data; struct node *n...
  • gongdileidechouzhu
  • gongdileidechouzhu
  • 2017-02-25 16:14:53
  • 1808

c++ 单链表基本操作

#include #include #include #include #include /*c++实现简单的单链表操作*/ using namespace std; typedef str...
  • cfan0801
  • cfan0801
  • 2012-03-13 21:01:44
  • 25063

第一篇博客—c语言单链表的基本操作

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和...
  • sakurakider
  • sakurakider
  • 2017-05-21 19:42:38
  • 670

单链表的基本操作-----图形解析

首先我们需要思考的是为什么需要单链表呢? 单链表和顺序表相比较,又有什么优点呢? 在顺序表中,当我们需要头插,或者在顺序表的中间位置插入元素时,就必须将后面的元素一一后移,再将需要插入的元...
  • qq_34992845
  • qq_34992845
  • 2016-12-31 01:12:28
  • 4475

数据结构—单链表的基本操作(源代码)

#include &amp;lt;stdio.h&amp;gt; #include &amp;lt;stdlib.h&amp;gt; typedef int Elemtype; typedef s...
  • weixin_40908734
  • weixin_40908734
  • 2018-01-29 11:43:00
  • 76

单链表基本操作详解

#  单链表基本操作 文中提到的内容的链接一并列在这里: 顺序表:http://blog.csdn.net/bitboss/article/details/51559175 冒泡排序:...
  • bitboss
  • bitboss
  • 2016-06-04 22:12:46
  • 3179

单链表的基本操作大全之C语言实现(一)

单链表的基本操作大全之C语言实现1. 单链表的定义链表是通过一组任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的也可以是不连续的。为了建立起数据元素之间的关系,对于每个数据元素除了存放...
  • men_wen
  • men_wen
  • 2016-10-20 21:43:10
  • 10903
收藏助手
不良信息举报
您举报文章:单链表的基本操作
举报原因:
原因补充:

(最多只允许输入30个字)