一、数据结构的学习方法
1、工具型
1》目的:
将现实生活中的各种复杂的数据,按照某一种方式分类,
按照这种分类将这些数据存储在计算机中,
然后,用各种编程语言(C语言)实现这些数据的处理。
2》学习内容:
1)数据的逻辑结构(数据之间的关系)
---》线性结构:线性表,栈,队列
---》非线性结构:树和图
2)数据的存储结构体
---》顺序存储
按照数据的逻辑关系,将每一个数据依次存储在一块连续的内存空间中。
---》链式存储
3)算法:
插入,删除,查找,排序,遍历等
3》学习的思路:
线性表----》存储-----》算法的实现
栈 ----》存储-----》算法的实现
队列 ----》存储-----》算法的实现
树和二叉树----》存储-----》算法的实现
查找
排序:插入排序,交换排序等
二、线性表
1、特征:
1》数据特征:
对非空表,a0是表头,无前驱;an-1是表尾,无后继;其它的每个元素ai有且仅有一个直接前驱(ai-1)和一个直接后继(ai+1)。
2》数据操作
可以在任何位置插入和删除数据
2、顺序存储
通常把线性表的顺序存储方式简称为顺序表。
1》顺序存储结构体
#define MAXSIZE 10
typedef int datatype;
typedef struct seqlist{
datatype data[MAXSIZE];
int last;
}seq_lsit,*seq_plist;
2》算法的实现:
1)初始化:
----》申请顺序表的空间
----》将last置-1
2)插入:
----》移动数据
----》将数据插入到指定位置
----》last加1
3)删除:
----》移动数据
----》将指定位置的数据删除
----》last减1
// seqlist.h
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 10
typedef int datatype;
typedef struct seqlist {
datatype data[MAXSIZE];
int last;
} seq_list, *seq_plist;
extern void init_seqlist(seq_plist *L);
extern bool insert_seqlist(seq_plist l, int i, datatype data);
extern bool isfull_seqlist(seq_plist l);
extern bool del_seqlist(seq_plist l, int i, datatype *d);
extern bool isempty_seqlist(seq_plist l);
extern void show_seqlist(seq_plist l);
#endif
// seqlist.c
#include "seqlist.h"
// 初始化顺序表
void init_seqlist(seq_plist *L)
{
*L = (seq_plist)malloc(sizeof(seq_list));
if (NULL == (*L)) {
perror("malloc");
exit(1);
}
(*L)->last = -1;
}
// 在l指向的顺序表中的i位置插入数据data,成功返回true,失败返回false
bool insert_seqlist(seq_plist l, int i, datatype data)
{
// 判断顺序表是否满
if (isfull_seqlist(l)) {
printf("顺序表已满!\n");
return false;
}
// 判断i是否合法
if (i < 0 || i > l->last + 1) {
printf("插入位置无效!\n");
return false;
}
// 表没有满,则可以插入数据
for (int j = l->last; j >= i; j--) {
l->data[j + 1] = l->data[j];
}
// 将data存储在i的位置
l->data[i] = data;
// 让last++
l->last++;
return true;
}
// 判断是否满
bool isfull_seqlist(seq_plist l)
{
if (l->last == MAXSIZE - 1)
return true;
else
return false;
}
// 在l指向的顺序表中删除i位置数据data,成功返回true,失败返回false
bool del_seqlist(seq_plist l, int i, datatype *d)
{
// 判断i是否合法
if (i < 0 || i > l->last) {
printf("删除位置无效!\n");
return false;
}
// 判断顺序表是否空
if (isempty_seqlist(l)) {
printf("顺序表已空!\n");
return false;
}
// 将i位置的数据返回
*d = l->data[i];
// 将i位置的数据删除
for (int j = i; j < l->last; ++j) {
l->data[j] = l->data[j + 1];
}
//让last减1
l->last--;
return true;
}
// 是否为空
bool isempty_seqlist(seq_plist l)
{
if (l->last == -1)
return true;
else
return false;
}
// 遍历顺序表
void show_seqlist(seq_plist l)
{
for (int i = 0; i <= l->last; ++i)
printf("%d\t", l->data[i]);
printf("\n");
}
// seqlist_test.h
#ifndef __SEQLIS_TEST_H__
#define __SEQLIS_TEST_H__
#include "seqlist.h"
extern bool insert_test(seq_plist l, datatype data);
extern bool del_test(seq_plist l, datatype data);
#endif
// seqlist_test.c
#include "seqlist_test.h"
#include "seqlist.h"
bool insert_test(seq_plist l, datatype data)
{
int i;
// 在顺序表中寻找插入data的位置i(让顺序表数据一次递增)
for (i = 0; i <= l->last; ++i) {
if (data < l->data[i])
break;
}
if (insert_seqlist(l, i, data)) {
return true;
} else {
return false;
}
}
bool del_test(seq_plist l, datatype data)
{
int i;
datatype t;
for (i = 0; i <= l->last; ++i) {
if (data == l->data[i])
break;
}
if (i > l->last) {
printf("%d不在顺序表中!\n", data);
return false;
}
if (del_seqlist(l, i, &t))
return true;
else
return false;
}
// test_main.c
/**
* 用顺序表存储一些正整数,输入正整数表示插入数据(比如输入3表示插入3),
* 输入负整数表示删除数据(比如输入-2表示删除2),输入字符表示退出程序。
* 插入和删除的过程中保持该表递增有序。
*/
#include "seqlist.h"
#include "seqlist_test.h"
int main(void)
{
seq_plist l = NULL;
datatype data = -1;
int ret = -1;
init_seqlist(&l); // 顺序表的初始化
while (1) {
printf("请输入一个整数:");
ret = scanf("%d", &data);
if (ret != 1) { // 输入为字符:退出程序
printf("Game Over!\n");
return 1;
} else if (data > 0) { // 输入为正数,按顺序插入到顺序表中
insert_test(l, data);
show_seqlist(l);
} else { // 输入为负数,在顺序表中删除对应的正数
del_test(l, -data);
show_seqlist(l);
}
}
return 0;
}