list.h

#ifndef LIST_H
#define LIST_H

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

//定义单链表结点
typedef struct _node
{
    int data;   //数据
    struct _node *next; //指向下一结点
}node,*pNode;

//创建链表
node *create_list();

//从链表头后插入数据
int insert_listHead(pNode head,int data);

//从链表尾后插入数据
int insert_listTail(pNode head, int data);

//遍历链表,并显示每个结点的数据
int show_listData(pNode head);

//求链表中的结点个数 (不包括链表头,指真正存放数据的结点数目)
int getNodeNum(pNode head);

//根据索引查找结点,找到返回所找结点 index=0,对应头结点(不存放数据) index=1,对应第一个数据结点
pNode find_nodeByIndex(pNode head,int index);

//根据数据查找第一个符合结点(后面也可能有结点的数据为所找数据),找到返回所找结点
pNode find_nodeByData(pNode head,int data);

//指定位置插入结点数据
int insert_dataInPos(pNode head,int data,int index);

//从链表中删除第index个结点  index范围为1-nodeNum
int delete_listIndex(pNode head,int index);

//删除整个链表
int delete_listAll(node **head);

//根据索引查找结点,找到修改其值
int modify_nodeByIndex(pNode head,int index,int data);

//将链表排序 ==0,升序  ==1,降序
int sort_list(pNode head,int sortType);

#endif // LIST_H

list.c

#include "list.h"

/*************单链表测试程序************/

//创建链表
node *create_list()
{
    pNode head = (pNode)malloc(sizeof(node));
    if(!head)
    {
        printf("malloc error!\n");
//        exit(-1);   //在iostream中定义
        return NULL;
    }

    head->data = ;
    head->next = NULL;  //不用指向head,由于不是循环链表且是单链表的尾结点的next腰指向NULL

    return head;
}

//从链表头后插入结点数据
int insert_listHead(pNode head,int data)
{
    //检测链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }

    pNode tmpNode = (pNode)malloc(sizeof(node));    //存放插入数据的结点
    if(!tmpNode)
    {
        printf("malloc error!\n");
        ;
    }

    //将插入数据存入要插入链表的结点
    tmpNode->data = data;
    //将tmpNode插入链表头后
    tmpNode->next = head->next;
    head->next = tmpNode;

    ;
}

//从链表尾后插入结点数据
int insert_listTail(pNode head, int data)
{
    //检测链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }

    pNode tmpNode = (pNode)malloc(sizeof(node));    //存放插入数据的结点
    if(!tmpNode)
    {
        printf("malloc error!\n");
        ;
    }

    //将插入数据存入要插入链表的结点
    tmpNode->data = data;
    //将tmpNode插入链表尾后
    tmpNode->next = NULL;   //插入链表插入链表尾后,成为新的尾结点,next要指向NULL

    pNode cur = head;
    //找到链表尾结点
    while(cur->next)    //尾结点的next指向NULL,跳出时的cur即为尾结点
    {
        cur = cur->next;
    }

    cur->next = tmpNode;    //原先尾结点的next指向插入结点

    ;
}

//遍历链表,并显示每个结点的数据
int show_listData(pNode head)
{
    //检测链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }

    //检测链表是否为空  (“为空”与“不存在”不同,为空说明只有一个结点,刚创建还未插入任何结点)
    if(!head->next)
    {
        printf("list isnot exist!\n");
        ;
    }

    pNode cur = head->next; //头结点数据域不保存插入数据,第二个结点才是第一个插入结点
    while(cur)
    {
        printf("%d ",cur->data);
        cur = cur->next;
    }
    printf("\n");

    ;
}

//求链表中的结点个数 (不包括链表头,指真正存放数据的结点数目)
int getNodeNum(pNode head)
{
    ;    //结点数目

    //判断链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }
    //------
    //判断链表是否为空
    if(!head->next)
    {
        printf("list is NULL!\n");
        ;
    }

    pNode cur = head->next;
    while(cur)
    {
        nodeNum++;
        cur = cur->next;
    }

    return nodeNum;
}

//根据索引查找结点,找到返回所找结点 index=0,对应头结点(不存放数据) index=1,对应第一个数据结点
pNode find_nodeByIndex(pNode head,int index)
{
    //判断链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        return NULL;
    }
    //------
    //判断链表是否为空
    if(!head->next)
    {
        printf("list is NULL!\n");
        return NULL;
    }
    //------
    int nodeNum = getNodeNum(head);
     || index > nodeNum)   //索引必须在允许范围 (1-nodeNum)
    {
        printf("pos out of range!\n");
        return NULL;
    }

    ;
    pNode cur =  head;
    while(cur)
    {
        i++;
        cur = cur->next;
        if(i==index)
            return cur;
    }

    return NULL;    //不返回,有警告
}

//根据数据查找第一个符合结点(后面也可能有结点的数据为所找数据),找到返回所找结点
pNode find_nodeByData(pNode head,int data)
{
    //判断链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        return NULL;
    }
    //------
    //判断链表是否为空
    if(!head->next)
    {
        printf("list is NULL!\n");
        return NULL;
    }

    pNode cur =  head->next;
    while(cur)
    {
        if(cur->data == data)
            return cur;
        cur = cur->next;
    }

    return NULL;
}

//指定位置插入结点数据
int insert_dataInPos(pNode head,int data,int index)
{
    //判断链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }
    //------
    //判断链表是否为空
    if(!head->next)
    {
        printf("list is NULL!\n");
        ;
    }
    //------
    int nodeNum = getNodeNum(head);
     || index > nodeNum)   //指定插入位置必须在允许范围
    {
        printf("pos out of range!\n");
        ;
    }

    //由于find_nodeByIndex的参数2范围限制为1-nodeNum,所以index在那里不能为1,要>=2
    )    //插入到位置1,相当于插入头结点后面
    {
        insert_listHead(head,data);
    }
    else    //index范围为2-nodeNum
    {
        pNode tmpNode = (pNode)malloc(sizeof(node));
        if(!tmpNode)
        {
            printf("malloc error!\n");
            ;
        }
        tmpNode->data = data;

        //获得插入位置的前一个结点-insertFrontNode(新数据结点插入到该结点后面)
        pNode insertFrontNode = find_nodeByIndex(head,index-);
        if(!insertFrontNode)   //未找到要被插入的结点
        {
            printf("no find insertFrontNode!\n");
            ;
        }

        //若index=2,相当于新数据结点插入到原数据结点1后面,所以需要找到原数据结点1
        tmpNode->next = insertFrontNode->next;
        insertFrontNode->next = tmpNode;
    }

    ;
}

//从链表中删除第index个结点  index范围为2-nodeNum
int delete_listIndex(pNode head,int index)
{
    //判断链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }
    //------
    //判断链表是否为空
    if(!head->next)
    {
        printf("list is NULL!\n");
        ;
    }
    //------
    int nodeNum = getNodeNum(head);
     || index > nodeNum)   //index必须在允许范围
    {
        printf("pos out of range!\n");
        ;
    }

    pNode front =  find_nodeByIndex(head,index-);    //找到要删除结点的前一个结点
    if(!front)
    {
        printf("no find!\n");
        ;
    }
    //---------
    pNode cur =  find_nodeByIndex(head,index);    //找到要删除结点
    if(!cur)
    {
        printf("no find!\n");
        ;
    }

    //删除该结点
    front->next = cur->next;
    free(cur);
    cur = NULL;

    ;
}

//删除整个链表
int delete_listAll(node **head)
{
    if(*head == NULL)
    {
        printf("list isnot exist!\n");
        ;
    }

    node *cur = (*head)->next;

    while(cur)
    {
        node *tmp = cur;

        //在free(tmp);后面,那时cur==tmp已经被释放,cur = cur->next不能正常执行了
        cur = cur->next;

        free(tmp);
        tmp = NULL;
    }

    free(*head);
    (*head) = NULL;

    ;
}

//根据索引查找结点,找到修改其值
int modify_nodeByIndex(pNode head,int index,int data)
{
    pNode modifyNode =  find_nodeByIndex(head,index); //找到要修改的结点
    modifyNode->data = data;

    ;    //不返回,有警告
}

//将链表排序 ==0,升序  ==1,降序
int sort_list(pNode head,int sortType)
{
    //判断链表是否存在
    if(!head)
    {
        printf("list isnot exist!\n");
        ;
    }
    //------
    //判断链表是否为空
    if(!head->next)
    {
        printf("list is NULL!\n");
        ;
    }

    int nodeNum = getNodeNum(head);

    int i,j;
    ; i < nodeNum - ; i++) //冒泡排序法
    {
        ; j < nodeNum -  - i; j++)
        {
            //第一次获取0,1结点 第二次获取1,0结点
            node *t_first = find_nodeByIndex(head,j+);
            node *t_second = find_nodeByIndex(head,j+);

            )   //升序
            {
                if(t_first->data > t_second->data)
                {
                    //交换2个结点的值
                    int tmp = t_first->data;
                    t_first->data = t_second->data;
                    t_second->data = tmp;
                }
            }
            )  //降序
            {
                if(t_first->data < t_second->data)
                {
                    int tmp = t_first->data;
                    t_first->data = t_second->data;
                    t_second->data = tmp;
                }
            }
            else
            {
                printf("parame error!\n");
                ;
            }

        }
    }

    ;
}

main.c

#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include "list.h"

using namespace std;

pNode tmpNode;
int main(void)
{
    //创建链表
    tmpNode = create_list();
    if(!tmpNode)
    {
        printf("malloc error!\n");
        ;
    }

    //插入1,3,5,7,9到链表中
    ;i<;i++)
    {
        insert_listHead(tmpNode,++i);
    }

    //插入结点数据
    insert_dataInPos(tmpNode,,);

    //获取结点数目
    printf("nodeNum=%d\n",getNodeNum(tmpNode));

    //遍历显示结点数据
    printf("showList: ");
    show_listData(tmpNode);

    //根据索引,返回第3个数据结点 index范围为1-nodeNum
    pNode t_node = find_nodeByIndex(tmpNode,);
    if(!t_node)    //有可能未找到,则返回NULL,那执行t_node->data会造成程序崩溃
        printf("no find!\n");
    else
        printf("t_data:data=%d\n",t_node->data);
    //返回数据为1的结点
    pNode t_node1 = find_nodeByData(tmpNode,);
    if(!t_node1)
        printf("no find!\n");
    else
        printf("t_data:data=%d\n",t_node1->data);

    //从链表中删除第1个结点  index范围为2-nodeNum
    delete_listIndex(tmpNode,);
    printf("showList: ");
    show_listData(tmpNode);

    //升序后显示结点数据
    sort_list(tmpNode,);
    printf("sortUp showList: ");
    show_listData(tmpNode);

    //降序后显示结点数据
    sort_list(tmpNode,);
    printf("sortUp showList: ");
    show_listData(tmpNode);

    //删除所有结点
    delete_listAll(&tmpNode);
    printf("showList: ");
    show_listData(tmpNode);

}

结果运行图:

数据结构之单链表(C实现)的更多相关文章

  1. Python数据结构之单链表

    Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...

  2. javascript数据结构之单链表

    下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...

  3. 数据结构之单链表的实现-java

    一.单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next ...

  4. python 数据结构之单链表的实现

    链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结点都包含了可以链接起来的地址信息,所以用一个变量就 ...

  5. 数据结构(一) 单链表的实现-JAVA

    数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...

  6. 数据结构 - 静态单链表的实行(C语言)

    静态单链表的实现 1 静态链表定义 静态链表存储结构的定义如下: /* 线性表的静态链表存储结构 */ #define MAXSIZE 1000 /* 假设链表的最大长度是1000 */ typede ...

  7. 数据结构 - 动态单链表的实行(C语言)

    动态单链表的实现 1 单链表存储结构代码描述 若链表没有头结点,则头指针是指向第一个结点的指针. 若链表有头结点,则头指针是指向头结点的指针. 空链表的示意图: 带有头结点的单链表: 不带头结点的单链 ...

  8. 【数据结构】单链表介绍及leetcode206题反转单链表python实现

    题目传送门:https://leetcode-cn.com/problems/reverse-linked-list/ 文章目录 单链表介绍 链表 概念 种类 优缺点 单链表(slist) leetc ...

  9. 数据结构(2):单链表学习使用java实现

    单链表是单向链表,它指向一个位置: 单链表常用使用场景:根据序号排序,然后存储起来. 代码Demo: package com.Exercise.DataStructure_Algorithm.Sing ...

  10. 数据结构:单链表结构字符串(python版)添加了三个新功能

    #!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...

随机推荐

  1. poj 3667 Hotel (线段树的合并操作)

    Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  2. 一起去打CS(codevs 5059)

    题目描述 Description 早就和lyk约好了去打cs,一直没找着时间,终于今天我家没人,他家也没人,总算可以出去了.但是偏偏天公不作美,某某人非要留那么多题要做.没办法只能尽快做完然后抓紧时间 ...

  3. 2018/3/4 Activiti教程之流程部署篇(与Springboot整合版)二

    首先我们来看下Activiti为我们自动生成的这四张用户相关的表 先看下USER表 我已经插入了一些数据,很明显,就是保存用户的信息的 看下GROUP 用户对应的分组信息 MEMBERSHIP 用户和 ...

  4. [NOIP2006] 普及组

    明明的随机数 STL真是偷懒神器 /*by SilverN*/ #include<algorithm> #include<iostream> #include<cstri ...

  5. 【intellij】intellij idea 建立与src级别的目录

    在使用三大框架时,通常会把配置文件放在自己新建的config文件夹里,以便编程.在 myeclipse里新建的config文件夹是Source Folder属性的 这样他的级别适合src一个级别,但是 ...

  6. Spring实战读书笔记

    Spring实战读书笔记 Spring-core Spring之旅 - DI 和 AOP 概念 spring 的Bean容器 spring 的 核心模块 Spring的核心策略 POJO 最小侵入式编 ...

  7. 洛谷——P1007 独木桥

    P1007 独木桥 题目背景 战争已经进入到紧要时间.你是运输小队长,正在率领运输部队向前线运送物资.运输任务像做题一样的无聊.你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在 ...

  8. 手游产品经理初探(二)从营销角度看loading界面

    近期開始写产品相关的专题,准备从细节入手去思考.总结一些不为人注意的细节地方. 今天给大家分享的是游戏里面都有的loading界面. 还是从几个在Facebook上排名靠前的Casino游戏的load ...

  9. keepalived + lvs marster 与 backup 之间的 高可用

    简介 keepalived 是linux下一个轻量级的高可用解决方案,它与HACMP实现功能类似,都可以实现服务或者网络的高可用,但是又有差别:hacmp是一个专业的.功能完善的高可用软件,它提供了H ...

  10. Ubuntu安装JDK及环境变量配置(sun java)

    捣鼓了尽一天的时间,终于把sun的java安装上了,不是openjava了,网上试了好多的方法好多都是不可以的,所以当自己成功后就立马把方法贴出来,以方便后来者少走弯路,此文的方法绝对可行! 这里先简 ...