什么是数据结构?
数据结构是计算机存储,管理数据的方式。数据必须依据某种逻辑联系组织在一起存储在计算机内,数据结构研究的就是这种数据的存储结构和数据的逻辑结构。
数据的逻辑结构的4种分类
逻辑结构
——数据本身之间的关系;
- 集合:数据元素除了属于同一个集合外,没有其他联系;
- 线性关系:数据元素之间呈现的是一对一的关系;
- 树型:数据元素之间呈现的是一对多的关系;
- 图型(网状):数据元素之间呈现的是多对多的关系;
物理结构(存储结构)
——逻辑结构在计算机中的实现;这里的存储指的是内存,不是外存;
- 顺序存储:所有数据挨在一起存放,连续存放;这种结构的 存储结构和逻辑结构是一致的;
- 链式存储:不在乎是否挨在一起,可连续存放,也可以不连续;
- 索引存储:在存储数据的同时,建立一个附加的索引表,即索引存储结构=数据文件+索引表
- 散列存储:通过构造相应散列函数,由散列函数的值来确定数据节点的存放地址
线性表
线性表定义
是具有相同数据类型的 n 个数据元素的有限序列。
线性表的特点
存在唯一的第一个元素
存在惟一的最后一个元素
除第一个元素外,每一个元素只有一个直接前驱
除最后一个元素外,每一个元素均只有一个直接后继
线性表的存储结构
顺序存储结构:顺序表
链式存储结构:链表
顺序表
定义
就是把线性表中的所有元素按照其逻辑顺序依次存储到指定位置开始的一块连续的存储区域。
顺序表的特点
- 在顺序表中,各元素的逻辑顺序跟物理顺序一致,第i项就存在第i个位置。
- 对顺序表中的所有元素,既可以顺序访问,也可以随机访问。
- 插入删除操作不方便,需要移动大量元素
顺序表的实现
数组的实现方式
头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include "stdio.h"
#include "stdlib.h"
#include "memory.h"
#include "string.h"
#include "Windows.h"
void fn();typedef struct Student
{char sname[20];int age;int stu;char gender[5];
}STU;typedef struct Stu
{STU stu_Arr[100];int length;
}S;S* List_Init();//初始化
void List_Append(S* list, STU data);//追加
void List_Insertion(S* list, int index, STU data);//插入
void List_Display(S* list);//显示
void List_Querying(S* list, int stu);//查询
void List_Del(S* list, int stu);//删除
void List_edit(S* list, int stu);//修改
void List_destruction(S * * list);//销毁
main函数
#include "02.h"int main()
{ fn();int choose;S* list = NULL;STU data;int index;while (1) { printf("请输入操作的指令数字\n");scanf(" %d", &choose);switch (choose){case 1: //初始化list=List_Init();break;case 2: //追加printf("请输入追加的学生姓名\n");scanf(" %s", &(data.sname));printf("请输入追加的学生年龄\n");scanf(" %d", &(data.age));printf("请输入追加的学生学号\n");scanf(" %d", &(data.stu));printf("请输入追加的学生性别\n");scanf(" %s", &(data.gender));List_Append(list, data);break;case 3: //插入 从一开始printf("请输入插入的学生姓名\n");scanf(" %s", &(data.sname));printf("请输入插入的学生年龄\n");scanf(" %d", &(data.age));printf("请输入插入的学生学号\n");scanf(" %d", &(data.stu));printf("请输入插入的学生性别\n");scanf(" %s", &(data.gender));printf("请输入插入的学生的序号\n");scanf(" %d", &index);List_Insertion(list, index, data);break;case 4: //显示List_Display(list);break;case 5: //查询printf("请输入查询的学生学号\n");scanf(" %d", &(data.stu));List_Querying(list,data.stu);break;case 6://删除printf("请输入删除学生的学号\n");scanf(" %d", &(data.stu));List_Del(list,data.stu);break;case 7:printf("请输入修改的学生的学号\n");scanf(" %d", &(data.stu));List_edit(list, data.stu);fn();break;case 8://销毁List_destruction(&list);break;case 9: //退出return 0;default:break;}}return 0;
}
封装函数
#include "02.h"void fn()
{printf(" 欢迎使用学生信息系统管理平台 \n");printf("* =========================== *\n");printf("* 1. 初始化 *\n");printf("* 2. 追加 *\n");printf("* 3. 插入 *\n");printf("* 4. 显示 *\n");printf("* 5. 查询 *\n");printf("* 6. 删除 *\n");printf("* 7. 修改 *\n");printf("* 8. 销毁 *\n");printf("* 9. 退出 *\n");printf("* =========================== *\n");
}S* List_Init()
{system("cls");fn();S* list = (S*)malloc(sizeof(S));if (list==NULL){printf("初始化失败\n");return NULL;}memset(list, 0, sizeof(S));printf("初始化成功!!!\n");return list;
}void List_Append(S* list,STU data){system("cls");fn();if (list == NULL){printf("未初始化\n");return;}list->stu_Arr[list->length] = data;list->length++;printf("添加成功!!!\n");}void List_Display(S* list){system("cls");fn();if (list == NULL){printf("未初始化\n");return;}printf("姓名 学号 年龄 性别\n");for (int i = 0; i < list->length; i++){printf("%s ", list->stu_Arr[i].sname);printf("%d ", list->stu_Arr[i].stu);printf("%d ", list->stu_Arr[i].age);printf("%s ", list->stu_Arr[i].gender);printf("\n");}}//1 2 3 4 5 6 7 8void List_Insertion(S* list,int index,STU data){system("cls");fn();if (list == NULL){printf("未初始化\n");return;}index -= 1;for (int i = list->length-1; i >= index ; i--){list->stu_Arr[i+1] = list->stu_Arr[i];}list->stu_Arr[index] = data;list->length++;printf("添加成功!!!\n");}void List_Querying(S* list, int stu)
{system("cls");fn();if (list == NULL){printf("未初始化\n");return;}if (list->length == 0){printf("不存在学生信息");return;}int flag = 0;printf("姓名 学号 年龄 性别\n");for (int i = 0; i < list->length; i++){if (list->stu_Arr[i].stu==stu){printf("%s ", list->stu_Arr[i].sname);printf("%d ", list->stu_Arr[i].stu);printf("%d ", list->stu_Arr[i].age);printf("%s ", list->stu_Arr[i].gender);flag = 1;printf("\n");}}if (flag==0){printf("不存在此学生\n");}
}//1 2 3 4 5 6 7 8
void List_Del(S* list, int stu)
{system("cls");fn();if (list == NULL){printf("未初始化\n");return;}if (list->length == 0){printf("不存在学生信息");return;}int flag = 0;for (int i = stu-1; i < list->length; i++){if (list->stu_Arr[i].stu==stu){list->stu_Arr[i] = list->stu_Arr[i + 1];flag = 1;}}if (flag == 0){printf("不存在此学生\n");}else{list->length--;printf("删除成功!!!\n");}}void List_edit(S* list,int stu)
{int choose;char name[20];char sex[5];int flag=0;system("cls");if (list == NULL){printf("未初始化\n");return;}if (list->length == 0){printf("不存在学生信息\n");return;}for (int i = 0; i < list->length; i++){if(list->stu_Arr[i].stu==stu){ flag = 1;while(1){printf("1.姓名 2.年龄 3.学号 4.性别\n请选择要修改的信息\n");scanf(" %d", &choose);switch (choose){case 1:printf("请输入修改后的学生姓名\n");scanf(" %s",&name);strcpy(list->stu_Arr[i].sname,name);break;case 2:printf("请输入修改后的学生年龄\n");scanf(" %d", &(list->stu_Arr[i].age));break;case 3:printf("请输入修改后的学生学号\n");scanf(" %d", &(list->stu_Arr[i].stu));break;case 4:printf("请输入修改后的学生性别\n");scanf(" %s",&sex );strcpy(list->stu_Arr[i].gender,sex);break;case 5:system("cls");return;default:break;}}}}if (flag==0){printf("未查到该学生\n\n");}
}void List_destruction(S**list)
{system("cls");fn();free(*list);*list = NULL;printf("销毁成功!!!\n");
}
指针的方式实现
头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
#include <assert.h>#define MaxSize 100
typedef struct Student
{char sname[20];int stu;int age;char gender[5];
}STU ;typedef struct Stu
{STU* list_Oreder;int length;
}S;void fn1();//菜单
void List_Init(S* list); //初始化
void List_Append(S* list, STU data);//追加
void List_Show(S list);//显示
void List_Insert(S* list, int index, STU data);//插入
void List_Check(S list, int stu);//查询
void List_Edit(S* list, int stu);//修改
void List_Del(S* list, int stu); //删除
void List_destroy(S* list);//销毁
main函数
#include "02.h"int main()
{S list = { NULL,0 };int choose;STU data;int index;while (1){fn1();printf("请输入选项\n");scanf(" %d", &choose);switch ( choose){case 1://初始化List_Init(&list);break;case 2://追加printf("请输入追加的学生姓名\n");scanf(" %s", &(data.sname));printf("请输入追加的学生年龄\n");scanf(" %d", &(data.age));printf("请输入追加的学生学号\n");scanf(" %d", &(data.stu));printf("请输入追加的学生性别\n");scanf(" %s", &(data.gender));List_Append(&list, data);break;case 3://插入printf("请选择要插入的地方\n"); scanf(" %d", &index);printf("请输入插入的学生姓名\n");scanf(" %s", &(data.sname));printf("请输入插入的学生年龄\n");scanf(" %d", &(data.age));printf("请输入插入的学生学号\n");scanf(" %d", &(data.stu));printf("请输入插入的学生性别\n");scanf(" %s", &(data.gender));List_Insert(&list,index,data );break;case 4://显示List_Show(list);break;case 5://查询printf("请输入查询的学生学号\n");scanf(" %d", &(data.stu));List_Check(list, data.stu);break;case 6://修改printf("请输入要修改信息的学生学号\n");scanf(" %d", &(data.stu));List_Edit(&list, data.stu);break;case 7://删除printf("请输入要删除信息的学生学号\n");scanf(" %d", &(data.stu));List_Del(&list, data.stu);break;case 8://销毁List_destroy(&list);break;case 9://退出return;default:break;}}return 0;}
封装函数
#include "02.h"void fn1()//菜单
{printf(" 欢迎使用学生信息系统管理平台 \n");printf("* =========================== *\n");printf("* 1. 初始化 *\n");printf("* 2. 追加 *\n");printf("* 3. 插入 *\n");printf("* 4. 显示 *\n");printf("* 5. 查询 *\n");printf("* 6. 修改 *\n");printf("* 7. 删除 *\n");printf("* 8. 销毁 *\n");printf("* 9. 退出 *\n");printf("* =========================== *\n");
}void List_Init(S *list) //初始化
{ list->list_Oreder=(STU*)malloc(sizeof(STU)*MaxSize);assert(list->list_Oreder);printf("初始化成功!!!\n");
}void List_Append(S *list,STU data)//追加
{if (list->list_Oreder == NULL){printf("未初始化\n");return;}list->list_Oreder[list->length] = data;list->length++;printf("追加成功!!!\n");
}void List_Show(S list) //显示
{ if (list.list_Oreder==NULL){printf("未初始化\n");return;}printf("姓名 学号 年龄 性别\n");for (int i = 0; i < list.length; i++){printf("%s ", list.list_Oreder[i].sname);printf("%d ", list.list_Oreder[i].stu);printf("%d ", list.list_Oreder[i].age);printf("%s ", list.list_Oreder[i].gender);printf("\n");}
}//3 1
void List_Insert(S* list, int index, STU data)//插入
{if (list->list_Oreder == NULL){printf("未初始化\n");return;}if (index > list->length){printf("插入位置不合适\n");return;}int ind = index - 1;if (ind<0||ind==99){printf("插入位置不合适\n");return;}for (int i = ind; i < list->length; i++){list->list_Oreder[i + 1] = list->list_Oreder[i];}list->list_Oreder[ind] = data;list->length++;printf("插入成功!!!\n");}void List_Check(S list, int stu)//查询
{if (list.list_Oreder == NULL){printf("未初始化\n");return;}int flag = 0;for (int i = 0; i < list.length; i++){if(list.list_Oreder[i].stu==stu){flag = 1;printf("%s ", list.list_Oreder[i].sname);printf("%d ", list.list_Oreder[i].stu);printf("%d ", list.list_Oreder[i].age);printf("%s ", list.list_Oreder[i].gender);printf("\n");}}if (flag==0){printf("未查到该学生\n");}}void List_Edit(S * list, int stu)//修改
{if (list->list_Oreder == NULL){printf("未初始化\n");return;}int flag = 0;int choose;char name[20];char sex[20];for (int i = 0; i < list->length; i++){if (list->list_Oreder[i].stu == stu){flag = 1;while(1){printf("1.姓名 2.年龄 3.学号 4.性别 5.退出");scanf(" %d", &choose);switch (choose){case 1:printf("请输入修改后的学生姓名\n");scanf(" %s", &name);strcpy(list->list_Oreder[i].sname, name);printf("修改成功!!!\n");break;case 2:printf("请输入修改后的学生年龄\n");scanf(" %d", &(list->list_Oreder[i].age));printf("修改成功!!!\n");break;case 3:printf("请输入修改后的学生学号\n");scanf(" %d", &(list->list_Oreder[i].stu));printf("修改成功!!!\n");break;case 4:printf("请输入修改后的学生性别\n");scanf(" %s", &sex);strcpy(list->list_Oreder[i].gender, sex);printf("修改成功!!!\n");break;case 5:system("cls");return;default:break;}}}}if (flag == 0){printf("未查到该学生\n");}
}void List_Del(S * list, int stu) //删除
{ if (list->list_Oreder == NULL){printf("未初始化\n");return;}int flag = 0;for (int i = 0; i < list->length; i++){if (list->list_Oreder[i].stu == stu){flag = 1;for (int j = i; j < list->length; j++){list->list_Oreder[j] = list->list_Oreder[j + 1];}list->length--;printf("删除成功!!!\n");}}if (flag == 0){printf("未查到该学生\n");}
}void List_destroy(S *list)//销毁
{if (list->list_Oreder == NULL){printf("未初始化\n");return;}free(list->list_Oreder);list->list_Oreder = NULL;printf("销毁成功!!!\n");
}
补充
数组清零
一般配合malloc函数使用
两个调试代码常用的方式
exit () 用于终止程序执行,输出一些参数,一般用0表示正常退出非0异常退出
assert(条件)条件为真,程序正常执行条件,为假,程序报错,退出
(#include <assert.h>)