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. Python基础之 一列表

    列表模块:listlen(list):列表元素个数max(list):列表元素最大值min(list):列表元素最小值list(seq):将元组转为列表list.append(obj):列表末尾添加新 ...

  2. HDU 5644 King's Pliot【费用流】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5644 题意: 每天都有p[i]个飞行员进行阅兵,飞行员只工作一天. m个休假公式,花费tt[i]元让 ...

  3. 洛谷 P1883 函数

    P1883 函数 题目描述 给定n个二次函数f1(x),f2(x),...,fn(x)(均形如ax^2+bx+c),设F(x)=max{f1(x),f2(x),...,fn(x)},求F(x)在区间[ ...

  4. 洛谷 P1555 尴尬的数字

    P1555 尴尬的数字 题目背景 Bessie刚刚学会了不同进制数之间的转换,但是她总是犯错误,因为她的两个前蹄不能轻松的握住钢笔. 题目描述 每当Bessie将一个数转换成新的进制时,她总会写错一位 ...

  5. 在Windows上安装Nexus

    在Windows上安装Nexus 学习了:https://www.cnblogs.com/yucongblog/p/6696736.html 下载地址:https://sonatype-downloa ...

  6. 自己动手写Android数据库框架

    前言 相信不少开发人员跟我一样,每次都非常烦恼自己写数据库,并且那些数据库语句也经常记不住.当然网上也有非常多非常好的数据库框架,你能够直接拿来用,可是 非常多时候我们的项目.特别是一个小型的Andr ...

  7. Session与Cookie解析

    Session和Cookie这两个对象也接触了比較长的时间了,今天就来总结一下. 首先,他们都是会话跟踪中经常使用的技术.Cookie在client记录信息来确定用户身份,Session在服务端记录信 ...

  8. Android 布局自适应屏幕

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenFzNjI3NjExMzA=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  9. 李洪强iOS开发之动态获取UILabel的bounds

    李洪强iOS开发之动态获取UILabel的bounds 在使用UILabel存放字符串时,经常需要获取label的长宽数据,本文列出了部分常用的计算方法. 1.获取宽度,获取字符串不折行单行显示时所需 ...

  10. Android自己定义无下划线ClickableSapn超链接文本样式

    近期在做评论的时候须要实现这样的效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamF2X2ltYmE=/font/5a6L5L2T/fontsize/ ...