使用单向链表保存大量数据的基础程序框架

以下程序只是作为一个简单的示例:(火车票订票系统)

#include "stdafx.h"

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

/*************************************预编译模块***************************************************/
#define  HEADER1 "|------------------------------book ticket sys--------------------------------|\n"
#define  HEADER2 "|  number  |start city|reach city|takeoffTime|reach time|  price   |ticketNum |\n"
#define  HEADER3 "|-----------------------------------------------------------------------------|\n"
#define  FORMAT  "|%-10s|%-10s|%-10s|%-11s|%-10s|%-10.2f|%-10d|\n"   //除了takeoffTime这一项,为保持上下对齐的美观,其它项数据都固定只占10位的长度

//定义火车票信息结构体
typedef struct _ticket
{
    char number[10]; //火车票的车次
    char startCity[10]; //火车票的出发城市
    char reachCity[10]; //火车票的到达城市
    char takeoffTime[10]; //火车票的出发时间
    char reachTime[10]; //火车票的到达时间
    float price; //火车票的票价
    int ticketNum; //火车票的剩余票数
}ticket;

//定义单向链表节点
typedef struct _node
{
    void *dat; //一般为结构体指针
    int size; //dat指向区域的大小,一般为结构体的大小
    struct _node *next; //后继节点
}node;

node *g_ticketList = NULL;

/*************************************链表模块***************************************************/
//创建链表
node *createList(int size)
{
    node *head = (node *)malloc(sizeof(node)); //给链表头结点分配内存空间
    if(!head)
    {
        printf("listHead malloc error!\n");
        return NULL;
    }

    head->dat = NULL; //链表头结点不存储数据,故指向NULL
    head->size = size; //链表的size一般为结构体的大小[size == sizeof(ticket)]
    head->next = NULL;

    return head;
}

//插入数据到链表尾节点后
int insertData_toListTail(node *head,void *dat)
{
    node *tmpNode = (node *)malloc(sizeof(node)); //定义一个存储插入数据的临时节点,插入该节点就相当于插入数据了
    if(!tmpNode)
    {
        printf("tmpNode malloc error!\n");
        return NULL;
    }

    //给临时节点的数据指针dat分配内存空间
    tmpNode->dat = malloc(sizeof(head->size)); //dat的类型一般为struct *,所以不再进行(void *)的强制类型转换
    if (!tmpNode->dat)
    {
        printf("tmpNode->dat malloc error!\n");
        return NULL;
    }
    tmpNode->dat = dat; //将要插入的数据保存在临时节点内
    tmpNode->size = head->size;

    node *cur = head; //定义当前节点
    while(cur->next)    //找到尾节点 [若链表只有一个头节点,则头节点就是尾节点]
    {
        cur = cur->next;
    }

    //将保存要插入数据的临时节点,插入到尾节点后
    cur->next = tmpNode;
    tmpNode->next = NULL; //此时,tmpNode变为尾节点
}

/*************************************火车票模块***************************************************/
//添加火车票,并保存在火车票信息链表中
int addTicket_toList(node *head)
{
    ticket *tmpTicket = (ticket *)malloc(sizeof(ticket)); //定义火车票信息的临时结构体指针
    if (!tmpTicket)
    {
        printf("tmpTicket malloc error!\n");
        return -1;
    }

    printf("请输入火车票的车次:");
    scanf("%s",tmpTicket->number);
    printf("请输入火车票的出发城市:");
    scanf("%s",tmpTicket->startCity);
    printf("请输入火车票的到达城市:");
    scanf("%s",tmpTicket->reachCity);
    printf("请输入火车票的出发时间:");
    scanf("%s",tmpTicket->takeoffTime);
    printf("请输入火车票的到达时间:");
    scanf("%s",tmpTicket->reachTime);
    printf("请输入火车票的票价:");
    scanf("%f",&tmpTicket->price);
    printf("请输入火车票的剩余票数:");
    scanf("%d",&tmpTicket->ticketNum);

    insertData_toListTail(head,tmpTicket); //插入火车票信息数据,到火车票信息链表尾节点后

    return 0;
}

//显示火车票信息链表中的所有节点数据
int showTicketList_allData(node *head)
{
    if(!head->next) //检测链表是否只有一个节点
    {
        printf("list only have one node,error!\n"); //链表只有一个节点,则打印错误信息,并返回
        return -1;
    }

    ticket *tmpTicket = (ticket *)malloc(sizeof(ticket)); //定义火车票信息的临时结构体指针
    if (!tmpTicket)
    {
        printf("tmpTicket malloc error!\n");
        return -1;
    }

    printf(HEADER1); //打印输出头信息
    printf(HEADER2);
    printf(HEADER3);
    for(node *cur=head->next;cur!=NULL;cur=cur->next) //由于头节点不保存数据,所以从第二个节点开始显示数据
    {
        tmpTicket = (ticket *)cur->dat; //将节点数据取出来,赋给临时结构体指针
        printf(FORMAT,tmpTicket->number,tmpTicket->startCity,tmpTicket->reachCity,tmpTicket->takeoffTime,tmpTicket->reachTime,tmpTicket->price,tmpTicket->ticketNum);
    }

    return 0;
}

void menu()
{
    printf("1. add ticket information    \n");
    printf("5. show ticket information   \n");
}

int _tmain(int argc, _TCHAR* argv[])
{
    int sel = 0;

    g_ticketList = createList(sizeof(ticket)); //创建火车票信息链表

    do
    {
        menu(); //显示菜单选项
        printf("请输入你的选项:");
        scanf("%d",&sel);

        switch(sel)
        {
            case 1:
            {
                addTicket_toList(g_ticketList); //添加火车票信息,到火车票链表中
                system("PAUSE"); //暂停
            }
            break;

            case 5:
            {
                showTicketList_allData(g_ticketList); //显示火车票信息链表中的所有节点数据
                system("PAUSE"); //暂停
            }
            break;
        }
        system("CLS"); //清屏
    } while (sel!=7);

    return 0;
}

添加火车票信息的示意图:

显示火车票信息的示意图

原文地址:https://www.cnblogs.com/linuxAndMcu/p/9716303.html

时间: 2024-10-21 06:21:54

使用单向链表保存大量数据的基础程序框架的相关文章

线性表的Java实现--链式存储(单向链表)

线性表的Java实现--链式存储(单向链表) 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 链式存储结构的线性表将采用一组任意的存储单元存放线性表中的数据元素.由于不需要按顺序存储,链表在插入.删除数据元素时比顺序存储要快,但是在查找一个节点时则要比顺序存储要慢. 使用链式存储可以克服顺序线性表需要预先知道数据大小的缺点,链表结构可以充分利用内存空间,实现灵活的内存动态管理.但是链式存储失去了数组随机存取的特点,同时增加了节点的指针域,空

链表(二)——单向链表的基本操作(创建、删除、打印、结点个数统计)

1.指针的联动 通过两个指针分别指向前驱和后继结点,并在单向链表上进行移动,当指针指向待处理的结点时,该结点的前驱也有指针指向. 2.设有一个无序单向链表,且数据域的值均不相同,使指针pmin指向最小值结点,并使指针prem指向最小值结点的前驱结点: 代码片段: for(p = head; p; q = p, p = p->next) { if(pmin->data > p->data) { pmin = p; prem = q; } } 3.单向链表的删除算法 注:使用mallo

链表(二):单向链表

一.什么是单向链表 在动态分配内存空间时,最常使用的就是“单向链表”(Single Linked List).一个单向链表节点基本上是由两个元素,即数据字段和指针所组成,而指针将会指向下一个元素在内存中的位置,如下图所示: 在“单向链表”中,第一个节点是“链表头指针”,指向最后一个节点的指针设为NULL,表示它是“链表尾”,不指向任何地方.例如列表A={a.b.c.d.x},其单向链表的数据结构如下图所示: 由于单向链表中所有节点都知道节点本身的下一个节点在哪里,但是对于前一个节点却没有办法知道

C语言:创建动态单向链表,创建完成后,输出每一个节点的数据信息。

// //  main.c //  dynamic_link_list // //  Created by ma c on 15/8/5. //  Copyright (c) 2015年 bjsxt. All rights reserved. //  要求:写一个函数建立有3名学生数据的动态单向链表,并输出链表中每个结点的所有内容. /* 建立动态链表的思想: 1.开辟一个新结点,并使p1,p2指向它: 2.读入一个学生数据给p1所指的结点: 3.head = NULL,n = 0; 4.判断读

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t[转]

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t Author:Echo Chen(陈斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:October 23h, 2014 1.ngx_list优势和特点 ngx_list _t是一个顺序容器,它实际上是动态数组和单向链表的结合体,扩容起来比动态数组简单的多,可以一次扩容一个数组,所以说它结合了 链表插入删除不需要移动的 和 数组下标快速索引 的优势

数据结构:单向链表系列6--交换相邻两个节点1(交换数据域)

给定一个单向链表,编写函数交换相邻 两个元素 输入: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 输出: 2 -> 1 -> 4 -> 3 -> 6 -> 5 -> 7 输入: 1 -> 2 -> 3 -> 4 -> 5 -> 6 输出: 2 -> 1 -> 4 -> 3 -> 6 -> 5 通过观察发现:当输入的与元素个数是单数的时候,最后一位不参与交换

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t

Author:Echo Chen(陈斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:October 23h, 2014 1.ngx_list优势和特点 ngx_list _t是一个顺序容器,它实际上是动态数组和单向链表的结合体,扩容起来比动态数组简单的多,可以一次扩容一个数组,所以说它结合了 链表插入删除不需要移动的 和 数组下标快速索引 的优势,设计非常让人叫绝,此外它还有以下特点: 链表中存储的元素是灵活的,可以

C++异常机制的实现方式和开销分析 (大图,编译器会为每个函数增加EHDL结构,组成一个单向链表,非常著名的“内存访问违例”出错对话框就是该机制的一种体现)

白杨 http://baiy.cn 在我几年前开始写<C++编码规范与指导>一文时,就已经规划着要加入这样一篇讨论 C++ 异常机制的文章了.没想到时隔几年以后才有机会把这个尾巴补完 :-). 还是那句开场白:“在恰当的场合使用恰当的特性” 对每个称职的 C++ 程序员来说都是一个基本标准.想要做到这点,就必须要了解语言中每个特性的实现方式及其时空开销.异常处理由于涉及大量底层内容,向来是 C++ 各种高级机制中较难理解和透彻掌握的部分.本文将在尽量少引入底层细节的前提下,讨论 C++ 中这一

数据结构与算法学习-单向链表的实现

链表(Chain本文所说链表均为单向链表,以下均简称单向链表)实际上是由节点(Node)组成的,一个链表拥有不定数量的节点.而向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的. 节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的.也就是说,节点拥有两个成员:储存的对象.对下一个节点的引用. 这样说可能大家不是很明白,我贴一张图大家可能更容易理解. package LinkedList; /** * <p><strong>