单链表基本操作

原创 2018年04月16日 19:17:27

思维导图

这里写图片描述

SList.h

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


typedef int DataType;

typedef struct SNode
{
    DataType data;
    struct SNode *_pNext;//保存下个节点的地址

}SNode, *PNode;


void SListInit(PNode* pHead);// 链表的初始化 
void SListPushBack(PNode* pHead, DataType data);// 尾插 
void SListPopBack(PNode* pHead);// 尾删 
void SListPushFront(PNode* pHead, DataType data);// 头插 
void SListPopFront(PNode* pHead);// 头删 
PNode SListFind(PNode pHead, DataType data);// 在链表中查找值为data的元素,找到后返回值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data);// 在pos位置插入值为data的结点 
void SListErase(PNode* pHead, PNode pos);// 删除pos位置的结点 
int SListSize(PNode pHead);// 获取链表中节点总数
int SListEmpty(PNode pHead);// 判断链表是否为空 
void SListDestroy(PNode* pHead);// 销毁链表
void PrintfList(PNode pHead);//打印链表

SList.c

#include "SList.h"

//初始化就是将链表头指针赋空,
//注意这里要传头指针的地址才能改变头指针的值
void SListInit(PNode* pHead)
{
    assert(pHead);//判断链表是否存在
    *pHead = NULL;
}
//创建新节点
PNode BuyNewNode(DataType data)
{
    PNode ptr = NULL;
    ptr = (PNode)malloc(sizeof(DataType)+sizeof(PNode));

    if (NULL == ptr)
    {
        printf("BuyNewNode failed!!!\n");
        return NULL;
    }
    //申请成功  
    ptr->data = data;
    ptr->_pNext = NULL;
    return ptr;
}

//打印链表
void PrintfList(PNode pHead)
{
    PNode ptr = pHead;
    if (pHead == NULL)
        return;
    while (ptr)
    {
        printf("%d-->", ptr->data);
        ptr = ptr->_pNext;
    }
    printf("NULL\n");

}

//尾插
void SListPushBack(PNode* pHead, DataType data)
{
    PNode pCur = NULL;
    assert(pHead);//判断链表是否存在

    if (*pHead == NULL)//判断链表是否为空
    {
        *pHead = BuyNewNode(data);//空就让头节点指向新节点
        return;
    }

    //1.先找到链表最后一个节点
    pCur = *pHead;
    while (pCur->_pNext)
    {
        pCur = pCur->_pNext;//朝后走一步
    }
    pCur->_pNext = BuyNewNode(data);

}

//尾删
void SListPopBack(PNode* pHead)
{
    assert(pHead);
    PNode pPre = *pHead;
    PNode pCur = *pHead;

    if (*pHead == NULL)
    {
        printf("链表已空,删除失败!!!\n");
        return;
    }

    //1.只有一个节点
    if (pCur->_pNext == NULL)
    {
        free(*pHead);
        *pHead = NULL;
        return;
    }
    //2.有一个以上节点
    while (pCur->_pNext)
    {
        pPre = pCur;//因为要找到倒数第二个节点,所以每走一步之前先保存
        pCur = pCur->_pNext;
    }
    free(pPre->_pNext);
    pPre->_pNext = NULL;
}

//头插
void SListPushFront(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指向原来的头节点

}

//头删
void SListPopFront(PNode* pHead)// 头删
{
    assert(pHead);
    PNode ptr = NULL;
    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的节点
PNode SListFind(PNode pHead, DataType data)
{
    PNode ptr = pHead;
    if (NULL == pHead)
    {
        printf("对不起,为空链表!!!\n");
        return NULL;
    }

    while ((ptr) && (ptr->data != data))//ptr中的data不是要找的且不为空就进入循环
    {
        ptr = ptr->_pNext;
    }

    //1.ptr为空,证明找不到
    if (NULL == ptr)
    {
        printf("对不起,找不到!!!\n");
        return NULL;
    }
    else
        return ptr;
}

int SListSize(PNode pHead)
{
    int count = 0;
    while (pHead)
    {
        pHead = pHead->_pNext;
        count++;
    }
    return count;
}

void SListInsert(PNode* pHead, PNode pos, DataType data)
{
    assert(pHead);

    //1.链表为空
    if (NULL == *pHead)
    {
        //1.如果链表为空,插入位置与头节点地址不相同,那么位置不合法
        if (pos == *pHead)
        {
            *pHead = BuyNewNode(data);
            return;
        }
        else
        {
            printf("位置不合法,插入失败!!!\n");
            return;
        }
    }

    //2.链表不为空
    //(1)头插:pos与头节点地址相等
    if (pos == *pHead)
        SListPushFront(pHead, data);
    //(2)pos与头节点位置不相等
    else
    {
        PNode pPre = *pHead;
        PNode pCur = *pHead;
        while ((pCur) && (pCur->_pNext != pos))
        {
            pCur = pCur->_pNext;
        }
        if (pCur == NULL)
        {
            printf("对不起,找不到该节点!!!\n");
            return;
        }
        else
        {
            pCur->_pNext = BuyNewNode(data);//插入新节点
            pCur->_pNext->_pNext = pos;//新节点链接pos处的节点
            pos = pCur->_pNext;//pos指向新节点
        }

    }
}


// 删除pos位置的结点 
void SListErase(PNode* pHead, PNode pos)
{
    assert(pHead);
    PNode ptr = *pHead;

    if (NULL == *pHead)
    {
        printf("链表已空,删除失败!!!\n");
        return;
    }

    //1.只有一个节点
    if ((*pHead)->_pNext == NULL)
    {
        if (*pHead == pos)
        {
            free(pos);
            *pHead = NULL;
            return;
        }

        else
        {
            printf("位置不合法,删除失败!!!\n");
            return;
        }
    }

    //2.有一个以上节点
    //(1)如果pos是头节点
    if (pos == *pHead)
    {
        *pHead = (*pHead)->_pNext;
        free(pos);
        return;
    }

    //(2)不是头结点
    while ((ptr) && (ptr->_pNext != pos) && (pos))
    {
        ptr = ptr->_pNext;
    }

    if ((ptr == NULL) || (pos == NULL))
    {
        printf("节点不存在,删除失败!!!\n");
        return;
    }
    else
    {
        ptr->_pNext = pos->_pNext;//链接起pos的下个节点
        free(pos);
    }
}
// 判断链表是否为空 
int SListEmpty(PNode pHead)
{
    if (pHead)
        return 1;
    return 0;
}

// 销毁链表
void SListDestroy(PNode* pHead)
{
    assert(pHead);
    PNode ptr = *pHead;
    PNode pMsg = *pHead;

    while (ptr)
    {
        ptr = ptr->_pNext;//ptr朝后走
        free(pMsg);//释放pMsg指向的空间

        if (ptr)
            pMsg = ptr;//pMsg跟着ptr走
    }
    *pHead = NULL;
}

test.c

#include "SList.h"
#include <windows.h>


int main()
{
    SNode SList;
    PNode pHead = &SList;
    SListInit(&pHead);// 链表的初始化
    SListEmpty(pHead);// 判断链表是否为空 
    SListInsert(&pHead, pHead, 40);
    PrintfList(pHead);
    //SListPushFront(&pHead, 0);
    //PrintfList(pHead);
    SListPushBack(&pHead, 5);//尾插
    SListPushBack(&pHead, 10);
    SListPushBack(&pHead, 3);
    //PrintfList(pHead);
    //SListPopBack(&pHead);//尾删
    //PrintfList(pHead);
    SListPushFront(&pHead, 0);//头插
    //PrintfList(pHead);
    //SListPopFront(&pHead);//头删
    PrintfList(pHead);
    // 在链表中查找值为data的元素,找到后返回值为data的结点
    SListFind(pHead, 3);
    SListSize(pHead);// 获取链表中节点总数
    SListInsert(&pHead, pHead->_pNext->_pNext , 20);// 在pos位置插入值为data的结点 
    PrintfList(pHead);
    SListErase(&pHead, pHead->_pNext->_pNext);// 删除pos位置的结点
    PrintfList(pHead);
    //SListDestroy(&pHead);// 销毁链表

    system("pause");
    return 0;
}

VB中获取逻辑磁盘的信息

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

单链表的基本操作

  • 2012年06月16日 16:18
  • 358KB
  • 下载

单链表基本操作java实现

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

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

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

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

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

c++ 单链表基本操作

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

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

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

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

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

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

#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
  • 3204
收藏助手
不良信息举报
您举报文章:单链表基本操作
举报原因:
原因补充:

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