数据结构与算法2-单链表的实现

     1.链表与顺序表的区别

        建议您先看下顺序表的实现这篇文章,再看单链表会更有助于理解。

数据结构与算法1-顺序表的实现icon-default.png?t=N7T8https://blog.csdn.net/qq_44940689/article/details/125785022        在顺序表的实现这篇文章中,这个里面我认为最关键的是抽象数据结构部分,结果如下(有疑问可移步上篇,欢迎交流和指正):

typedef struct 
{
    int num;
    char name[20];
    float score;
} Stu;

#define MAX 100
typedef struct
{
    Stu data[MAX];
    int last;
} Seqlist;

        Seqlist即是所创建的顺序表。抛开其中last这个成员(没有它也能实现功能,只不过更麻烦些),那么Seqlist是一个结构体数组,本质上是一个数组,而顺序表和数组在某些不影响理解的情况下可以认为是一个东西,具体可以看下这个区别:
顺序表与数组的联系和区别icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/687412172这样的话这个顺序表就有一个特点-数组的特点,即元素在地址上是相连的,那么知道首成员的的地址,全部成员的地址也是确定的; 这个特点有优点也有缺点。

优点:1、地址相连——存储密度大;2、地址确定——可以随机存取任一元素

缺点:1、在插入、删除某一元素时,需要移动大量其他元素;2、浪费大量存储空间;3、属于静态存储形式,数据元素的个数不能够自由扩充。

        就像你和舍友6个人去上早八,去的晚了没有6个座位连起来的位置了,这时你们只能分开去做——像链表一样,零散的但是有位置。(这里只是针对于地址上的比喻)。

2.单链表

2.1抽象数据结构

        如图一个长方形就是一个节点,它们连起来就是链表。那它们是怎么连起来的呢?可以看到每个长方形是由两个正方形构成的,一个是放你要储存的数据,一个是指向下一个节点的地址,分别称为数据与和地址域,这样就连了起来。定义代码如下:

typedef int data_t;

typedef struct list{
    data_t data;//数据
    struct list * next;//指向下一个数据节点的指针
}List;

2.2写头文件,确定需求

#ifndef _LIST_H
#define _LIST_H

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

typedef int data_t;

typedef struct list{
    data_t data;//数据
    struct list * next;//指向下一个数据节点的指针
}List;

//创建表
List * List_create();

//判断表数据是否为空
int List_is_empty(List * list);

//插入数据
int List_insert_data_pos(List * list,data_t data,int pos);
int List_insert_data_head(List * list,data_t data);//头插
int List_insert_data_tail(List * list,data_t data);//尾插

//删除数据
int List_delete_data_pos(List * list,int pos);
int List_delete_data(List * list,data_t data);

//查询数据
int List_search_data_pos(List * list,int pos,data_t * data);
int List_search_data(List * list,data_t data);

//修改数据
int List_change_data(List * list,data_t olddata,data_t newdata);
int List_change_data_pos(List * list,int pos,data_t newdata);

//销毁表
int List_destroy(List **list);

int List_show(List * list);

#endif

2.3写功能函数,实现需求

#include "list.h"

//创建表
List * List_create()
{
    List * list = (List *)malloc(sizeof(List));
    if(NULL == list){
        printf("list malloc errror\n");
        return NULL;
    }
    list->data = -1;
    list->next = NULL;
    return list;
}

//判断表数据是否为空
int List_is_empty(List * list)
{
}

//插入数据
int List_insert_data_pos(List * list,data_t data,int pos)
{
    //新的节点创建
    List * new_node = (List *)malloc(sizeof(List));
    if(NULL == new_node){
        printf("new_node malloc error\n");
        return -1;
    }
    new_node->data = data;
    new_node->next = NULL;
    
    List * p = list;
    int i;
    for(i=0;i<pos-1;i++){
        p = p->next;
    }

    new_node->next = p->next;
    p->next = new_node;

    return 0;

}

int List_insert_data_head(List * list,data_t data)
{
    //新的节点创建
    List * new_node = (List *)malloc(sizeof(List));
    if(NULL == new_node){
        printf("new_node malloc error\n");
        return -1;
    }
    new_node->data = data;
    new_node->next = NULL;
    //链接到表内
    new_node->next = list->next;
    list->next = new_node;
    return 0;
}

//插入数据
int List_insert_data_tail(List * list,data_t data)
{
    //找到尾巴节点
    List * p = list;
    while(p->next != NULL){
        p = p->next;
    }
    //创建新的节点
    List * new_node = (List *)malloc(sizeof(List));
    if(NULL == new_node){
        printf("new_node malloc error\n");
        return -1;
    }

    new_node->data = data;
    new_node->next = NULL;
    //将新的节点链接到表内
    p->next = new_node;

    return 0;
}

//删除数据
int List_delete_data_pos(List * list,int pos)
{

}
//按值删除数据
int List_delete_data(List * list,data_t data)
{
    List * p = list;
    while(p->next->data != data){
        p = p->next;
    }

    List * q = p->next;

    p->next = p->next->next;
    free(q);
    q = NULL;

    return 0;
}

//查询数据
int List_search_data_pos(List * list,int pos,data_t * data)
{
}
int List_search_data(List * list,data_t data)
{

}

//修改数据
int List_change_data(List * list,data_t olddata,data_t newdata)
{

}
int List_change_data_pos(List * list,int pos,data_t newdata)
{

}

//销毁表
int List_destroy(List **list)
{
}

int List_show(List * list)
{
    List * p = list;
    while(p->next != NULL){
        printf("%d ",p->next->data);
        p = p->next;
    }
    printf("\n");
}

2.4主函数,检验需求

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

#include "list.h"

int main(int argc, char *argv[])
{ 
    List * list = NULL;
    list = List_create();

    int i;
    for(i=0;i<10;i++){
        List_insert_data_tail(list,i);
    }

    
    List_insert_data_head(list,1024);
    
    List_insert_data_pos(list,111,4);
    
    List_show(list);
    
    List_delete_data(list,7);

    List_show(list);
    return 0;
} 

3.后续

        这个是单链表,对于节点里的内容再稍加改动,即可完成后面双链表和循环链表的实现,下篇进行双链表的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值