前言
这是在华清学习的第五个周末,这一周主要学习的是数据结构。老师说数据结构是一门非常庞大的学科,单单是数据结构里的一个小分支,单拎出来一周都未必可以学透,因此这周的数据结构课程里更多的是思维方向的学习,学习数据结构的思维方式和算法、拓宽思路,大方向上,利用好的数据结构和算法,来提升程序的执行效率,合理的使用内存资源;现阶段上,学习数据结构可以提高代码的质量,提升代码量,强化对C语言知识的理解和认识,养成编程思维、逻辑思维。
这一周里主要的学习内容有:顺序表、链表、栈、队列、数和哈希数组,每一部分都很重要,主要是算法思路和程序实现方面的问题。
周一
数据结构概况和顺序表
一、数据结构概括
1.1 什么是数据结构
老教授说:程序 = 数据结构 + 算法;
数据结构是独立于计算机和编程语言的,是一种处理数据的思想;
数据结构是研究 数据逻辑关系、存储、及操作的知识;
数据:能够输入到计算机中的描述客观事物的信息集合 (需要计算机处理的对象);
结构:数据之间的关系;
算法:对特定问题求解的一种描述;
1.2 数据元素和数据项
数据元素:一组数据;
数据项:某组数据中的某个独立数据;
数据对象:若干相同数据元素的集合;
1.3 数据结构三要素
逻辑结构、存储结构、运算。
逻辑结构:数据元素之间的关系,与存储无关,独立于计算机。主要指数据间的逻辑关系,例如邻接关系、直接前驱、直接后继等。
存储结构:指数据在计算机,尤其是内存中的分布方式。
运算:对数据的操作,例如增删改查、加减乘除、排序等。
1.4 数据的逻辑结构
主要分为线性结构和非线性结构。
线性关系:一对一。
树形关系:一对多。
网状关系:多对多。
1.5 数据的存储结构
顺序存储:数据元素之间在内存上是连续存储的,一般通过数组方式实现。
链式存储:数据元素之间在内存上不一定是连续存储的(可以是,也可以不是),一般通过链表方式实现。
索引存储:根据数据元素的特殊字段(称为关键字key),计算数据元素的存放地址,然后数据元素按地址存放。
1.6 算法(操作)
增删改查、加减乘除、排序翻转等。
二、顺序表
2.1 基本概念
存储结构:顺序存储,C语言中通过数组实现,在内存中以连续的空间进行存储。
逻辑结构:线性结构(一对一),除首元素和尾元素外,有唯一前趋和唯一后继(与数组的区别)。
算法:增删改查、排序、去重,遍历(学习阶段用来看现象)。
2.2 代码实现
main.c
#include "sq_list.h"
int main(int argc, const char *argv[])
{
LIST_t *L = create_list();
if(NULL == L){
puts("创建顺序表失败!!");
return 0;
}
int choose = 0;
while(1){
print_menu();
printf("请输入所需模式-->");
scanf("%d",&choose);
switch(choose){
case 1: //任意位置插入数据
insert_pos(L);
show_list(L);
break;
case 2: //任意位置删除数据
delet_pos(L);
show_list(L);
break;
case 3: //根据姓名查找数据元素
name_find(L);
break;
case 4:
name_change(L);
break;
case 5:
sort_name(L);
show_list(L);
break;
case 6:
rm_sm_name(L);
show_list(L);
break;
case 7:
break;
default:
puts("模式选择错误,请重新输入!!");
break;
}
if(7 == choose){
return 0;
}
}
show_list(L);
return 0;
}
sq_list.c
#include "sq_list.h"
void print_menu(){
puts("");
puts("----------------------");
puts("|1、插入 2、删除|");
puts("|3、查找 4、修改|");
puts("|5、排序 6、去重|");
puts("|7、退出 |");
puts("----------------------");
}
//创建顺序表;
LIST_t *create_list(void){
LIST_t *L = (LIST_t *)malloc(sizeof(LIST_t));
if(NULL == L){
puts("创建顺序表失败!!");
return NULL;
}
L->index = 0;
memset(L,0,sizeof(LIST_t));
return L;
}
//地址传递的方式创建顺序表;
void create_list_2(LIST_t **L){
}
//释放顺序表
int free_list(LIST_t **L){
if(NULL == L||NULL == *L){
puts("传入参数非法!!");
return -1;
}
free(*L);
*L = NULL;
return 0;
}
//任意插入数据
int insert_pos(LIST_t *L){
if(NULL == L){
puts("传入位置参数非法!!");
return -1;
}
if((L->index == N)){
puts("顺序表已满,无法继续添加!!");
return -1;
}
int i = 0;
STU_t stu_inf;
int pos = 0;
printf("请输入要插入的位置-->");
scanf("%d",&pos);
if(pos>(L->index)){
puts("所输入的位置参数过大!!");
return -1;
}
printf("请输入学生信息-->");
scanf("%s%d%d",stu_inf.name,&(stu_inf.age),&(stu_inf.score));
for(i=L->index;i>pos;i--){
L->stu_list[i] = L->stu_list[i-1];
}
L->stu_list[pos] = stu_inf;
L->index++;
return 0;
}
//任意位置删除数据
int delet_pos(LIST_t *L){
if(NULL == L){
puts("传入表参数非法!!");
return -1;
}
if(0 == L->index){
puts("表为空,无数据可删除!!");
return -1;
}
int i = 0;
int pos = 0;
printf("请输入要删除的位置-->");
scanf("%d",&pos);
if(pos>(L->index)){
puts("所输入的位置参数过大!!");
return -1;
}
for(i = pos;i<(L->index)-1;i++){
L->stu_list[i] = L->stu_list[i+1];
}
L->index--;
return 0;
}
//遍历顺序表
int show_list(LIST_t *L){
if(NULL == L){
puts("传入表参数非法!!");
return -1;
}
if(0 == L->index){
puts("表为空,无数据可遍历!!");
return -1;
}
int i = 0;
for(i=0;i<(L->index);i++){
printf("姓名:%s\t年龄:%d\t成绩:%d\n",
L->stu_list[i].name,
L->stu_list[i].age,
L->stu_list[i].score);
}
return 0;
}
//根据姓名查找数据元素
int name_find(LIST_t *L){
if(NULL == L){
puts("传入表参数非法!!");
return -1;
}
if(0 == L->index){
puts("表为空,无数据可查找!!");
return -1;
}
int i = 0;
char name[20];
printf("请输入要查询的学生姓名--->");
scanf("%s",name);
for(;i<(L->index);i++){
if(0 == strcmp(L->stu_list[i].name,name)){
puts("已找到:");
printf("姓名:%s\t年龄:%d\t成绩:%d\n",
L->stu_list[i].name,
L->stu_list[i].age,
L->stu_list[i].score);
break;
}
}
if(i==L->index){
puts("未找到!!");
}
return 0;
}
//根据姓名修改数据项
int name_change(LIST_t *L){
if(NULL == L){
puts("传入表参数非法!!");
return -1;
}
if(0 == L->index){
puts("表为空,无数据可修改!!");
return -1;
}
int i = 0;
char name[20];
int new_score = 0;
printf("请输入要查询的学生姓名--->");
scanf("%s",name);
for(;i<(L->index);i++){
if(0 == strcmp(L->stu_list[i].name,name)){
puts("已找到:");
puts("请输入学生新的成绩:");
scanf("%d",&new_score);
L->stu_list[i].score = new_score;
printf("姓名:%s\t年龄:%d\t成绩:%d\n",
L->stu_list[i].name,
L->stu_list[i].age,
L->stu_list[i].score);
break;
}
}
if(i==L->index){
puts("未找到!!");
}
return 0;
}
//根据学生的成绩继续排序
int sort_name(LIST_t *L){
if(NULL == L){
puts("传入表参数非法!!");
return -1;
}
if(0 == L->index){
puts("表为空,无数据可排序!!")