2022-03-29 11:22阅读: 72评论: 0推荐: 0

数据结构 - (2)链表

链表整体代码及相关操作:

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

//声明结点结构
typedef struct ListNode {
    int data;
    struct ListNode *next;
} ListNode;


//声明链表结构
typedef struct LinkList {
    ListNode head;
    int length;
} LinkList;


//初始化结点
ListNode *init_listnode(int val) {
    ListNode *p = (ListNode *)malloc(sizeof(ListNode));
    p->data = val;
    p->next = NULL;
    return p;
}


//初始化链表
LinkList *init_linklist() {
    LinkList *l = (LinkList *)malloc(sizeof(LinkList));
    l->head.next = NULL;
    l->length = 0;
    return l;
}


//清除结点
void clear_listnode(ListNode *node) {
    if (node == NULL) return ;
    free(node);
    return ;
}


//清除链表
void clear_linklist(LinkList *l) {
    if (l == NULL) return ;
    ListNode *p = l->head.next, *q;
    while (p) {
        q = p->next;
        clear_listnode(p);
        p = q;
    }
    free(l);
    return ;
}


//数据(结点)插入
int insert(LinkList *l, int ind, int val) {
    if (l == NULL) return 0;
    if (ind < 0 || ind > l->length) return 0;
    ListNode *p = &(l->head), *node = init_listnode(val);
    while (ind--) {
        p = p->next;
    }
    node->next = p->next;
    p->next = node;
    l->length += 1;
    return 1;
}

//删除操作
int erase(LinkList *l, int ind) {
    if (l == NULL) return 0;
    if (ind < 0 || ind >= l->length) return 0;
    ListNode *p = &(l->head), *q;
    while (ind--) {
        p = p->next;
    }
    q = p->next->next;
    clear_listnode(p->next);
    p->next = q;
    l->length -= 1;
    return 1;
}

void output(LinkList *l) {
    printf("LinkList(%d) : ", l->length);
    //(for循环中跳出条件为当p为空,不为空则持续循环直到p为空)
    for (ListNode *p = l->head.next; p; p = p->next) {
        printf("%d -> ", p->data);
    }
    printf("NULL\n");
    return ;
}

//测试30次
#define MAX_OP 30

int main() {
    srand(time(0));
    LinkList *l = init_linklist();
    for (int i = 0; i < MAX_OP; i++) {
        int op = rand() % 3;    //随机数在0-2之间
        int ind = rand() % (l->length + 1); //插入位置0 到 lenght
        int val = rand() % 100;
        switch (op) {
            //0,1 都进行插入操作
            case 0:
            case 1: {
                printf("insert %d at %d to LinkList = %d\n", 
                       val, ind, insert(l, ind, val));
            } break;
            //2 进行删除操作
            case 2: {
                printf("erase item at %d from LinkList = %d\n", 
                      ind, erase(l, ind));
            } break;
        }
        output(l);
        printf("\n");
    }
    clear_linklist(l);
    return 0;
}

 

附:链表定义(发文)

    链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
    使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表双向链表以及循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。

本文作者:HanaKoo

本文链接:https://www.cnblogs.com/HanaKoo/p/16070469.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   HanaKoo  阅读(72)  评论(0编辑  收藏  举报
@format
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 Tiny Light(TV动画《地缚少年花子君》ED)(翻自 鬼頭明里) 柚卟
Tiny Light(TV动画《地缚少年花子君》ED)(翻自 鬼頭明里) - 柚卟
00:00 / 00:00
An audio error has occurred.

作词 : Saku

作曲 : Saku

優しさに触れて残る温度

消えないまま 愛しいと言えたら

心は軽くなるかな

閉ざした扉の向こうで

微かな声が聴こえてる

踏み出すことさえも出来ないから

孤独に寄り添ってる

まだこの胸の中 生きづいたまま

小さな灯し火のような想いを

風に吹かれぬように

雨に濡れないように

ずっと抱きしめてた

ただ 真っ直ぐなまま願う強さも

泣き出しそうになる脆い自分も

君が居なきゃ知らなかったんだよ

偶然の中で運命を見つけた

瞳閉じる度 記憶の海 漂っては

深い夢のあと

面影を探してたんだ

変わらないモノクロの日々に

君が色を添えてくから

滲んだ過去さえもいつの間にか

意味を持ち始めてる

まだこの胸の中隠したままの

痛いほど愛おしい こんな思いを

いつか消えてしまうその前に

届けたい人は 君だけなんだ

どんな涙も どんな笑顔も

全ては君のためにあるから

まだこの胸の中 生きづいたまま

小さな灯し火のような想いを

風に吹かれぬように

雨に濡れないように

ずっと抱きしめてた

ただ 真っ直ぐなまま願う強さも

泣き出しそうになる脆い自分も

君が居なきゃ知らなかったんだよ

偶然の中で運命を見つけた

君がいるだけで世界は変わった