内容概括:

一、链表简介及创建列表

二、添加节点

三、链表排序

代码编译平台:

CentOS 6.4 64b

一、链表简介及创建列表:

传统数组缺点:

传统数组长度需要事先设定,不能改变,内存由系统自动分配,函数调用结束后系统自动回收,不能跨函数调用。

链表:

内存空间不要求连续,增删操作灵活。

链表由头指针、头结点、首节点、普通节点和尾节点组成。

每个节点有两个部分,一个是数据,一个是存放下一个节点的节点指针。

头指针:指向头结点的指针,通过头指针便可对链表进行所有操作。

头结点:链表的第一个节点,其不存放有效数据,其指针指向首节点。

首节点:第一个存放有效数据的节点。 

尾节点:存放有效数据,但其指针是空(NULL)。

注:除头结点之外,其他都是有效节点,如果只有头结点,即头结点的指针为空,则表示此链表为空链表。

节点的结构体

struct NODE
{
    int data;
    struct NODE * pNext;
};

通过CreateList函数实现链表的创建。  

首先创建出头指针和头节点,并创建操作指针pOperate方便后续操作,代码如下:

struct NODE * pMntHead = (struct NODE *) malloc(sizeof(struct NODE *)) ;
struct NODE * pOperate = pMntHead;
pOperate->pNext = NULL;

创建节点:

创建数据节点和临时节点指针pMnt,实用此指针完成数据节点的数据存储

int value; //通过用户输入取值
struct NODE * pMnt = (struct NODE *) malloc(sizeof(struct NODE *));
pMnt->data = value;

节点连接:

将数据节点的指针置空(将每个新节点当做尾节点看待),并将链表的尾节点指向此节点(节点连接)

pMnt->pNext = NULL;
pOperate->pNext = pMnt;

最后移动pOperate指针,准备添加下一个节点

pOperate = pMnt;

至此,一个只有一个数据节点的链表就添加完成了,其他数据节点类似操作, 完整代码如下:

#include <stdio.h>
#include <malloc.h>

struct NODE
{
    int data;
    struct NODE * pNext;
}; //定义节点

struct NODE * CreateList(void); //创建链表,并返回链表地址
void ShowList(const struct NODE *); //显示链表数据

int main(void)
{
    struct NODE * pHead;
    pHead = CreateList();
    ShowList(pHead);
    printf("\n");
    ;
}

struct NODE * CreateList(void)
{
    int list_len;
    int i;
    int value;
    struct NODE * pMntHead = (struct NODE *) malloc(sizeof(struct NODE *)) ; //创建头指针和头结点
    struct NODE * pOperate = pMntHead;
    pOperate->pNext = NULL;

    printf("Input the list length: ");
    scanf("%d", &list_len);
    ; i<list_len; i++)
    {
        printf("Input the value of %d : ", i);
        scanf("%d", &value);
        struct NODE * pMnt = (struct NODE *) malloc(sizeof(struct NODE *)); //创建一个新的数据节点

        pMnt->data = value;
        pMnt->pNext = NULL;
        pOperate->pNext = pMnt;  //连接节点
        pOperate = pMnt;
    }
    return pMntHead;  //返回所创建链表的头结点地址
}

// 显示一个链表的所有内容
void ShowList(const struct NODE * pMntHead)
{
    while(pMntHead->pNext != NULL)
    {
        pMntHead = pMntHead->pNext;
        printf("%d ", pMntHead->data);
    }
}

演示:

[root@ly ~]#
[root@ly ~]# ls
x.c
[root@ly ~]# gcc x.c
[root@ly ~]# ls
a.out  x.c
[root@ly ~]# ./a.out
Input the list length:
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  : 

[root@ly ~]#
[root@ly ~]#

添加节点:

思路:

创建新节点,然后遍历整个链表找到尾节点并连接到新节点。

代码: 

void AddValue(struct NODE * pMntHead, int new_value)
{
    struct NODE * pMnt = (struct NODE *) malloc(sizeof(struct NODE *));
    pMnt->data = new_value;
    pMnt->pNext = NULL;

    while(pMntHead->pNext != NULL)
        pMntHead = pMntHead->pNext;

    pMntHead->pNext = pMnt;
}

main函数代码如下:

#include <stdio.h>
#include <malloc.h>

struct NODE
{
    int data;
    struct NODE * pNext;
};

struct NODE * CreateList(void);  //参考链表创建文
void ShowList(const struct NODE *); //参考链表创建文
void AddValue(struct NODE *, int);

int main(void)
{
    struct NODE * pHead;
    pHead = CreateList();
    ShowList(pHead);
    printf("\n");
    AddValue(pHead, );
    ShowList(pHead);
    printf("\n");

    ;
}

演示:

[root@ly ~]#
[root@ly ~]# ./a.out
Input the list length:
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  : 

[root@ly ~]#
[root@ly ~]#

三、链表排序:

思路:

将链表的所有节点通过数组保存,通过数组进行升序排列,最后重新组合链表。 

函数代码如下:

void SortList(struct NODE * pHead)
{
    ;
    struct NODE * tmp, * pMntHead;
    pMntHead = pHead; 

        // 获取链表有效节点的长度(个数)
    while(pMntHead->pNext != NULL)
    {
        pMntHead = pMntHead->pNext;
        arry_len++;
    }
    pMntHead = pHead;  //操作指针复位

    // 动态创建相应长度的节点指针数组
    struct NODE ** node_addrs = (struct NODE **) malloc(arry_len * sizeof(struct NODE *));
        //将节点地址保存到指针数组中
    ; i<arry_len; i++)
    {
        node_addrs[i] = pMntHead->pNext;
        pMntHead = pMntHead->pNext;
    }
    //对数组进行重新排序
    ; i<arry_len; i++)
        ; j<arry_len--i; j++)
            ]->data)
            {
                tmp = node_addrs[j];
                node_addrs[j] = node_addrs[j+];
                node_addrs[j+] =  tmp;
            }
    pMntHead = pHead;
    // 重新连接各节点
    ; i<arry_len; i++)
    {
        pMntHead->pNext = node_addrs[i];
        pMntHead = node_addrs[i];
    }
    pMntHead->pNext = NULL;
    free(node_addrs);
}

全部代码:

#include <stdio.h>
#include <malloc.h>

struct NODE
{
    int data;
    struct NODE * pNext;
};

struct NODE * CreateList(void);
void ShowList(const struct NODE *);
void SortList(struct NODE *);

int main(void)
{
    struct NODE * pHead;
    pHead = CreateList();
    ShowList(pHead);
    printf("\n");

    SortList(pHead);
    ShowList(pHead);
    printf("\n");

    ;
}

void SortList(struct NODE * pHead)
{
    ;
    struct NODE * tmp, * pMntHead;
    pMntHead = pHead; 

    while(pMntHead->pNext != NULL)
    {
        pMntHead = pMntHead->pNext;
        arry_len++;
    }
    pMntHead = pHead; 

    struct NODE ** node_addrs = (struct NODE **) malloc(arry_len * sizeof(struct NODE *));

    ; i<arry_len; i++)
    {
        node_addrs[i] = pMntHead->pNext;
        pMntHead = pMntHead->pNext;
    }
    ; i<arry_len; i++)
        ; j<arry_len--i; j++)
            ]->data)
            {
                tmp = node_addrs[j];
                node_addrs[j] = node_addrs[j+];
                node_addrs[j+] =  tmp;
            }
    pMntHead = pHead;
    ; i<arry_len; i++)
    {
        pMntHead->pNext = node_addrs[i];
        pMntHead = node_addrs[i];
    }
    pMntHead->pNext = NULL;
    free(node_addrs);
}

struct NODE * CreateList(void)
{
    int list_len;
    int i;
    int value;
    // create head point and the first node
    struct NODE * pMntHead = (struct NODE *) malloc(sizeof(struct NODE *)) ;
    struct NODE * pOperate = pMntHead;
    pOperate->pNext = NULL;

    printf("Input the list length: ");
    scanf("%d", &list_len);
    ; i<list_len; i++)
    {
        printf("Input the value of %d : ", i);
        scanf("%d", &value);
        struct NODE * pMnt = (struct NODE *) malloc(sizeof(struct NODE *));

        pOperate->pNext = pMnt;
        pOperate = pMnt;
        pOperate->data = value;
        pOperate->pNext = NULL;
    }
    return pMntHead;
}

void ShowList(const struct NODE * pMntHead)
{
    while(pMntHead->pNext != NULL)
    {
        pMntHead = pMntHead->pNext;
        printf("%d ", pMntHead->data);
    }
}

演示:

[root@ly ~]#
[root@ly ~]#
[root@ly ~]# gcc a.c
[root@ly ~]# ./a.out
Input the list length:
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  :
Input the value of  : 

[root@ly ~]#
[root@ly ~]#
[root@ly ~]#

C(C++)/ 数据结构 链表的更多相关文章

  1. Python—数据结构——链表

    数据结构——链表 一.简介 链表是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构.由一系列节点组成的元素集合.每个节点包含两部分,数据域item和指向下一个节 ...

  2. (js描述的)数据结构[链表](4)

    (js描述的)数据结构 [链表](4) 一.基本结构 二.想比于数组,链表的一些优点 1.内存空间不是必须连续的,可以充分利用计算机的内存,事项灵活的内存动态管理. 2.链表不必再创建时就确定大小,并 ...

  3. 数据结构和算法(Golang实现)(12)常见数据结构-链表

    链表 讲数据结构就离不开讲链表.因为数据结构是用来组织数据的,如何将一个数据关联到另外一个数据呢?链表可以将数据和数据之间关联起来,从一个数据指向另外一个数据. 一.链表 定义: 链表由一个个数据节点 ...

  4. Redis数据结构—链表与字典的结构

    目录 Redis数据结构-链表与字典的结构 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 Redis字典的使用 Re ...

  5. Redis数据结构—链表与字典

    目录 Redis数据结构-链表与字典 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 哈希算法 解决键冲突 rehas ...

  6. [数据结构]——链表(list)、队列(queue)和栈(stack)

    在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...

  7. delphi.数据结构.链表

    链表作为一种基础的数据结构,用途甚广,估计大家都用过.链表有几种,常用的是:单链表及双链表,还有N链表,本文着重单/双链表,至于N链表...不经常用,没法说出一二三来. 在D里面,可能会用Contnr ...

  8. JavaScript数据结构——链表

    链表:存储有序的元素集合,但不同于数组,链表中的元素在内存中不是连续放置的.每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 好处:可以添加或移除任意项,它会按需扩容 ...

  9. JavaScript数据结构——链表的实现

    前面楼主分别讨论了数据结构栈与队列的实现,当时所用的数据结构都是用的数组来进行实现,但是数组有的时候并不是最佳的数据结构,比如在数组中新增删除元素的时候需要将其他元素进行移动,而在javascript ...

  10. js 实现数据结构 -- 链表

    原文: 在 Javascript 中学习数据结构与算法. 概念: 链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的.每个 元素由一个存储元素本身的节点和一个指向下一个元素的引 ...

随机推荐

  1. rhel7 单用户修改root密码

    rhel7密码忘记的时候,可以通过单用户模式修改密码 1.修改 引导文件,添加rw init=/sysroot/bin/sh ,ctrl+x启动 2.切换根chroot /sysroot3.使用pas ...

  2. 卡巴斯基2017激活教程_卡巴斯基2017用授权文件KEY激活的方法

    原创:天诺时空 更新时间:2016-11-09   2016年9月7日,卡巴斯基2017版全新上市,卡巴斯基依旧为大家奉上满足您所有需求的安全软件产品,为不同年龄层.不同人群给予全方位保护,同时延续卡 ...

  3. Windows 10不能拨L2TP协议的VPN

    之前是Windows 10版本1607版本14393.102升级14393.187过后,突然出现不能拨公司防火墙的L2TPVPN了. 网上众说纷纭,原来遇到这个问题的人真不少,不过我是第一次遇到.结合 ...

  4. [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)

    Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或 ...

  5. HTML 学习笔记 JavaScript(面向对象)

    现在让我们继续跟着大神的脚步前进 学习一下JavaScript中的面向对象的思想,其实作为一个iOS开发者,对面向对象还是比较熟悉的,但是昨晚看了一下Js中的面向对象,妈蛋 一脸萌比啊.还好有大神.让 ...

  6. bash/shell编程学习(3)

    接上节继续, 1. 从键盘读取输入内容 #!/bin/bash read -p 'please input something:' input echo 'your input:' $input 运行 ...

  7. [LeetCode] Sum of Left Leaves 左子叶之和

    Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two l ...

  8. [LeetCode] Remove K Digits 去掉K位数字

    Given a non-negative integer num represented as a string, remove k digits from the number so that th ...

  9. [LeetCode] Data Stream as Disjoint Intervals 分离区间的数据流

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  10. [LeetCode] Additive Number 加法数

    Additive number is a positive integer whose digits can form additive sequence. A valid additive sequ ...