首页 > 其他分享 >数据结构-单向链表的实现(c语言)

数据结构-单向链表的实现(c语言)

时间:2024-05-28 22:32:29浏览次数:15  
标签:LinkList int 单向 void list pCurrent 链表 数据结构 指针

链表的定义:

链表是由一系列的结点组成的,每个结点包含两个域,分别是指针域(*next)与数据域(data)。

单向链表的实现

//.h文件

#ifnde DXLB_H
#define DXLB_H

//定义结点结构体
typedef struct LINKNODE
{
    struct LINKNODE* next;    //指向下一个结点的指针
    int data;                //数据域
}LinkNode;

//定义链表结构体
typedef struct LINKLIST
{
    LinkNode* head;        //定义链表的头结点
    int size;              //记录链表中的结点数
}LinkList;


//定义打印函数的函数指针
typedef void(*PRINTLINKNODE)(void*);

//初始化链表
LinkList* Init_LinkList();

//指定位置插入
void Insert_LinkList(LinkList* list,int pos,void* node);

//根据位置删除
void RemoveByPos_LinkList(LinkList* list,int pos);

//查找
int Find_LinkList(LinkList* list,void* data);

//打印
void Print_LinkList(LinkList* list,PRINTLINKNODE print);

//获取链表的长度
int Size_LinkList(LinkList* list);

//返回第一个结点的数据
void* Front_LinkList(LinkList* list);

//释放链表内存
void FreeSpace_LinkList(LinkList* list);

#endif
//.c 文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//初始化链表
LinkList* Init_LinkList()
{
    //申请内存空间
    LinkList* list = (LinkList*)malloc(sizeof(LinkList));

    //初始化
    list->head = (LinkNode*)malloc(sizeof(LinkNode));

    head->next = NULL;
    //头结点的数据域不保存数据
    head->data = NULL;

    //将链表的结点个数置为0
    list->size = 0;

    return list;
}

//指定位置插入
void Insert_LinkList(LinkList* list,int pos,void* node)
{
    if(list = NULL)    return;

    if(node == NULL)    return;

    if(pos < 0 || pos > list->size)    pos = list->size;

    //申请一个新的结点来存放所要存储的数据
    LinkNode* newnode = (LinkNode*)malloc(sizeof(LinkNode));
    newnode->data = node;
    newnode->next = NULL;

    //需要移动指针,设置一个辅助指针
    LinkNode* pCurrent = list->head;
    for(int i = 0; i < pos; i++)
        pCurrent = pCurrent->next;
    newnode->next = pCurrent->next;
    pCurrent->next = newnode;

    list->size++;
    
}

//根据位置删除
void RemoveByPos_LinkList(LinkList* list,int pos)
{
    if(list == NULL)    return;
    if(pos < 0 || pos >= list->size)    return;

    //将指针移动到需要删除的结点的前面
    LinkNode* pCurrent = list->head;
    for(int i = 0; i < pos; i++)
        pCurrent = pCurrent->next;

    //将需要删除的结点临时存储
    LinkNode* pNext = pCurrent->next;
    pCurrent->next = pNext->next;
    
    //释放需要删除结点的内存
    free(pNext);

    list->size--;
}

//查找
int Find_LinkList(LinkList* list,void* data)
{
    if(list == NULL)    return -1;
    if(data == NULL)    return -1;

    //需要移动指针,设置一个临时指针变量
    LinkNode* pCurrent = list->head->next;
    
    int pos = -1;
    for(int i = 0; i < list->size; i++)
    {
        if(pCurrent->data == &data)
        {
            pos = i;
            break;
        }
        pCurrent = pCurrent->next;
    }
        
    return pos;
}

//打印
void Print_LinkList(LinkList* list,PRINTLINKNODE print)
{
    if(list == NULL)    return;

    LinkNode* pCurrent = list->head->next;
    for(int i = 0; i < list->size; i++)
    {
        print(pCurrent);
        pCurrent = pCurrent->next;
    }
}

void MyPrint(void* data)
{
    LinkNode* p = (LinkNode*)data;
    printf("%d ",p->data);
}

//获取链表的长度
int Size_LinkList(LinkList* list)
{
    if(list == NULL)    return -1;

    return list->size;
}

//返回第一个结点的数据
void* Front_LinkList(LinkList* list)
{
    if(list == NULL)    return NULL;

    return list->head->next;
}

//释放链表内存
void FreeSpace_LinkList(LinkList* list)
{
    if(list == NULL)    return;

    if(list != NULL)
    {
        LinkNode* pCurrent = list->head;
        while(pCurrent != NULL)
        {
            LinkNode* pNext = pCurrent->next;
            free(pCurrent);
            pCurrent = pNext;
        }

        free(list);
        list->size = 0;
    }
}

int main()
{
    return 0;
}

函数指针与指针函数:

        函数指针:其本质是一个指针变量,该指针指向这个函数。

        定义一个函数指针:int (*fun)(int x,int y);       返回值类型 (*函数名)(参数1,参数2);

        指针函数:返回指针的函数,  int* fun(int x,int y);

指针数组与数组指针:

        指针数组:指针的数组,本质是一个数组;指针数组是指多个指针变量存储在数组当中。

                           例如:int* arr[3];             这是存放了三个 int* 类型的指针数组

        数组指针:指向数组的指针,本质是一个指针变量。

                           例如:int (*a)[3];        这里指  指针变量 a  指向存放三个int 类型数据的数组

指针常量与常量指针:

        指针常量:

                int* const p;

                p 指向的地址不能更改

                但是可以通过 p 改变所指向的地址的变量的值,也就是可以通过指针赋值  *p = 100

        常量指针:

                const int* p;

                p的指向可以更改

                但是不能通过 p 来修改所指向的变量的值,也就是不能通过指针赋值

标签:LinkList,int,单向,void,list,pCurrent,链表,数据结构,指针
From: https://blog.csdn.net/m0_63713177/article/details/139272745

相关文章

  • 数据结构—线性表
    线性表的定义:    线性表是具有相同特性的数据元素的一个有限序列,类似于数组。    线性表中的元素都有一个直接前驱和直接后继,除了第一个首元素和最后一个元素线性表的实现:    使用线性表模拟动态数组的实现:                //.......
  • 反转链表
    leetcode:206.需求:反转链表原链表:graphLRA-->B-->C-->D-->null反转后:graphRLD-->C-->B-->A-->null graphLR D-->C-->B-->A-->null双指针法:/***Definitionforsingly-linkedlist.*publicclassListNode{*......
  • 【LeetCode算法】第83题:删除排序链表中的重复元素
    目录一、题目描述二、初次解答三、官方解法四、总结一、题目描述二、初次解答1.思路:双指针法,只需遍历一遍。使用low指向前面的元素,high用于查找low后面与low不同内容的节点。将具有不同内容的节点链接在low后面,实现重复元素的删除。2.代码:/***Definitionfor......
  • 数据结构初阶 栈
    一.栈的基本介绍1.基本概念栈是一种线性表是一种特殊的数据结构栈顶:进行数据插入和删除操作的一端另一端叫做栈底压栈:插入数据叫做压栈压栈的数据在栈顶出栈:栈的删除操作叫做出栈出栈操作也是在栈顶栈遵循一个原则叫做后进先出(比如说子弹的弹夹其实就是一种设......
  • 实现双链表各种基本运算的算法
    实验三:实现双链表各种基本运算的算法一、实验目的与要求目的:领会双链表存储结构和掌握双链表中各种基本运算算法设计。内容:编写一个程序dlinklist.cpp,实现双链表的各种基本运算和整体建表算法(假设链表的元素类型ElemType为char),并在此基础上设计一个程序exp2-3.cPp,......
  • 数据结构的直接插入排序(C语言版)
    一.直接插入排序的基本概念1.直接插入排序的基本思想将数组分为已排序和未排序两部分。每次从未排序部分取出一个元素,将其插入到已排序部分的合适位置,使得已排序部分保持有序。重复步骤2,直到整个数组有序。2.排序的工作原理假设前i-1个元素已经有序,现在要将......
  • 数据结构:队列
    目录队列的概念和结构队列的实现结构定义初始化判空入队列出队列返回队头元素返回队尾元素返回size销毁 队列的概念和结构队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstInFirstOut)入队列:进行插入操......
  • 数据结构--哈夫曼树
    一、实验目的1、掌握二叉树的逻辑结构、存储结构及基本操作;2、熟练掌握哈夫曼树在实际问题中的应用;3、针对计算机领域复杂工程问题,能够综合运用数据结构的基本理论和设计方法,设计出合理的算法。二、实验内容 “烽火连三月,家书抵万金”可见古人传递信息的不容易。古人用烽......
  • 设计链表
    leetcode:707题这题基本涵盖链表的的常用操作,获取第n个节点的值(从零开始)头部插入节点尾部插入节点第n个节点前插入节点删除第n个节点C#:publicclassMyLinkedList{publicintcount{get;set;}privateNodedummyHead;publicMyLinkedList(){......
  • 【算法】合并k个已排序的链表
    ✨题目链接:NC51合并k个已排序的链表✨题目描述 合并k 个升序的链表并将结果作为一个升序的链表返回其头节点。数据范围:节点总数 0≤......