数据结构:2-3天 (内功---重点)----命令行等都是外功
数据结构的基本概念:
-逻辑结构
-物理结构
-运算结构
几个常用的数据结构:(一定要会写代码)
堆栈(栈)
队列
链表
二叉树(有序二叉树)
某人高人说过:软件就是数据结构和算法组成。
数据结构是 相互之间存在一定关系的 数据的 集合。
---------------------------------------
数据结构是计算机存储、组织数据的方式。
----------------------------
数据结构的选择直接影响计算机程序的运行效率(时间复杂度)和存储效率(空间复杂度)
------------------------------------------------------------------
计算机的程序设计=算法+数据结构
数据结构的三个层次:
--抽象层---逻辑结构---人脑角度
--结构层---物理结构---计算机角度
--实现层---运算结构---应用角度
逻辑结构的分类:(人脑的角度)
集合结构(集)------结构中的元素除了同 属于一个集合之外 没有其他关系。-----公共汽车上的乘客,彼此没有任何关系。
线性结构(线性表)--结构中的元素 是一对一的前后 关系。如数组,排队(重点)
树形结构(树)——————结构中的元素是 一对多的父子 关系。 如目录结构等
网状结构(图)------结构中的元素 是多对多的交叉映射关系。
----物理结构的分类:
——顺序结构----数据存放在一片 连续的 内存地址中。
——链式结构————链式结构的元素存放在 不连续的 内存地址中,因此存储时 按节点
存储,而不只是存储数据。一个节点包括数据和下一个节点的地址。
优缺点:
顺序结构:随机访问方便,插入删除效率低,空间使用率低
链式结构:插入删除方便,随机访问效率低,空间使用率高
顺序结构和链式结构从效果上是互补的。
-----逻辑结构与物理结构的关系图:
---------------------------------------------------
数据结构 | 表 | 树 | 图
---------------------------------------------------
顺序 | 顺序表(数组)| 顺序树 |复合
---------------------------------------------------
链式 | 链式表(链表)| 链式树 |复合
----------------------------------------------------
复合就是既有顺序结构,又有链式结构。
-----运算结构:
在应用中需要提供的函数。
增删改查
创建与销毁----分配内存、回收内存
插入与删除----增加元素、删除元素
获取与修改----获取元素、修改元素
排序和查找----元素排序、查找元素
注意:修改函数、排序函数不是必须提供的。
需要掌握的4种常见的数据机构(能写):
堆栈、队列、链表、有序二叉树(重点中的重点)
算法:(能写)
排序算法:冒泡、选择、插入、快速、归并
查找算法:线性查找、二分查找(有序)
堆栈:后进(压入、push)先出(弹出、pop) , 先进后出(反向)
12345顺序进去 54321出来
堆栈的实现---基于数组(顺序结构)
定义一个数组arr+一个下标位置top
入栈:
arr[top] = data;
top++;
出栈:
top--;
return arr[top];
注意:入栈覆盖数据,出栈没必要清空数据。
栈的运算结构(需要提供的各种函数)
1、创建函数、销毁函数:
2、入栈函数、出栈函数(增删)
3、判空函数、判满函数(如果空则不能出栈,如果满则不能进栈)
4、查看栈顶而不出栈(查看)
5、获得栈的元素个数
栈的结构:(Stack)----注意:数组也可以通过给定一个地址+长度来给出。
struct Stack{
int* arr;//数组的首地址
int cap;//数组的容量(实际上就是长度)
int top;//当前的位置
};
数组是一个常指针,不能改变指向的指针。
sa.h
1 #ifndef _SA_H
2 #define _SA_H//防止重复include
3 //各种的声明都定义在头文件中包括(结构,变量,函数)
5 //各种实现都定义在.c文件中 比如变量赋值/函数代码
6 #include <sys/types.h>
7 typedef struct Stack{
8 int * arr;//数组的首地址,需要分配内存的。
9 size_t cap;//整数,size_t,非负的
10 size_t top;//当前的下标,也是栈顶
11 }STACK;//typedef起别名
12 void stack_init(STACK* stack,size_t cap);//初始化栈
13 void stack_deinit(STACK* stack);//销毁栈
14 int stack_full(STACK* stack);//判断堆栈是否满
15 int stack_empty(STACK* stack);//判断堆栈是否空
16 void stack_push(STACK* stack,int data);//入栈
17 int stack_pop(STACK* stack);//栈顶出栈
18 int stack_top(STACK* stack);//看栈顶而不出栈
19 size_t stack_size(STACK* stack);//栈的长度或者栈的元素数量
20
21 #endif
//数据结构的文件,都要写头文件
头文件和.c文件:
各种声明放在头文件中,各种实现放在.c文件中
sa.c
1 #include <stdlib.h> //malloc需要<<stdlib.h>>
2 #include "sa.h"
3 void stack_init(STACK* stack,size_t cap){//初始化栈
//分配一个cap*4大小的内存空间,并由指向arr位置
4 stack->arr = malloc(cap*4);//结构指针的成员用->头; *(stack).arr
//为什么要乘以4;因为这里是int元素,单个长度为4,cap个元素
5 stack->cap = cap;//容量,给栈的指定容量
6 stack->top = 0;//栈顶为0;
7 }
8 void stack_deinit(STACK* stack){//销毁栈
9 free(stack->arr);//释放内存
10 stack->arr = NULL;//地址不能是无效地址
11 stack->cap = 0;//消除隐患防止麻烦
12 stack->top = 0;
13 }
14 int stack_full(STACK* stack){//判断堆栈是否满
15 return stack->top >= stack->cap;
16 }
17 int stack_empty(STACK* stack){//判断堆栈是否空
18 return !stack->top;//==> =0;
19 }
20 void stack_push(STACK* stack,int data){//入栈
21 stack->arr[stack->top] = data;
22 stack->top++;
23 }
24 int stack_pop(STACK* stack){//栈顶出栈
25 stack->top--;
26 return stack->arr[stack->top];
27 }
28 int stack_top(STACK* stack){//看栈顶而不出栈
29 return stack->arr[stack->top - 1];
30 }
31 size_t stack_size(STACK* stack){//栈的长度或者栈的元素数量
32 return stack->top;
33 }
01test.c
1 #include <stdio.h>
2 #include "sa.h"
3
4 int main()
5 {
6 STACK stack;
7 stack_init(&stack,10);
8 int i = 0;
9 while(!stack_full(&stack))
10 {
11 stack_push(&stack,i++);
12 }
13
14 while(!stack_empty(&stack))
15 {
16 printf("%d\n",stack_pop(&stack));
17 }
18 }
//gcc 01test.c sa.c //编译连接
堆栈的实现--基于链式表(链式结构)
主要实现:
基于链式表的堆栈没有满,只有空。
入栈的步骤:
(1)先创建一个新的节点,新节点的data是传入的数据,新
节点的next就是原来的top。
(2)堆栈的top = 新节点的地址。
出栈的步骤:
(1)先销毁栈顶节点
(2)让堆栈的top = 原来栈顶节点的next
首先写一个节点结构:
struct StackNode{
int data;//存储数据
struct StackNode* next;//存下一个节点的地址
};
堆栈的结构:
struct Stack{
struct Stack * top;//栈顶节点的地址
};
sh.h
//新建节点的地址指向下一个节点的地址的是原来的栈顶
//top=top.next;
1 #ifndef _SL_H
2 #define _SL_H
3 #include <sys/types.h>
4 typedef struct StackNode{
5 int data;//数据
6 struct StackNode * next;//下一个节点的地址
7 }STACK_NODE;
8
9 typedef struct Stack{
10 STACK_NODE* top;//栈顶节点
11 }STACK;
12
13 void stack_init(STACK* stack);//初始化为空堆栈
14 void stack_deinit(STACK* stack);//释放所有节点,并置空
15 int stack_empty(STACK* stack);//判断是否为空
16 void stack_push(STACK* stack,int data);//入栈
17 int stack_pop(STACK * stack);//出栈
18 int stack_top(STACK* stack);//查看栈顶而不出栈
19 size_t stack_size(STACK* stack);//栈中的元素数量
20 #endif
-----------------------------------------------------------------------------
sh.c
1 #include <stdlib.h>
2 #include "sh.h"
3 static STACK_NODE* create_node(int data,STACK_NODE* next){//新建节点并返回
4 //只限于本文件使用
//为什么不用void,是因为 创建节点后要返回其地址便于以后使用?
//为什么用static?只有本文件能使用,外部不能使用。
5 STACK_NODE * node = malloc(sizeof(STACK_NODE));//分配内存,用于存储地址
6 node->data = data;//新建节点的数据
7 node->next = next;//指向上一个节点的地址
8 return node;
9 }
10 //删除一个节点并返回下一个节点的地址
11 static STACK_NODE* destroy_node(STACK_NODE* node){
12 STACK_NODE * next = node->next;//删除一个节点A,首先把A节点指向的下一个地址(下一个节点的地址)存起来
13 free(node);//释放节点
14 return next;//把前面存起来的地址返回。
15 }
16 void stack_init(STACK* stack){//初始化为空堆栈
17 stack->top = NULL;
18 }
19 void stack_deinit(STACK* stack){//释放所有节点,并置空
20 while(stack->top/* !=NULL */)
21 {//每循环一次,销毁一个节点;当stck->top真时,销毁节点
22 stack->top = destroy_node(stack->top);
23 }
24 }
25 int stack_empty(STACK* stack){//判断是否为空
26 return ! stack->top; // !=0 !=NULL在前面加上!即可。
27 }
28 void stack_push(STACK* stack,int data){//入栈
29 //先执行函数create_node,再赋值
30 stack->top = create_node(data,stack->top);//原来的栈顶作为新节点的下一个指向;
31 }
32 int stack_pop(STACK * stack){//出栈
33 int data = stack->top->data;//先把栈顶节点的数据取出来;栈顶节点的data
34 stack->top = destroy_node(stack->top); //销毁上一个节点
35 return data;
36 }
37 int stack_top(STACK* stack){//查看栈顶而不出栈
38 return stack->top->data;
39 }
40 size_t stack_size(STACK* stack){//栈中的元素数量
41 size_t size = 0;
42 STACK_NODE* node = NULL;//为什么要定义node?top不能改变,top一改变就弹出数据了。
//在这里相当于复制了一个top
43 for (node = stack->top;node;node=node->next)
44 {//意思是:node=stack->top;设置node初始值为栈顶;node;在这里判断node是非为NULL; node=node->next;使其指向为下一个节点。
45 ++size;
46 }
47 return size;
48 }
------
测试代码:
1 #include <stdlib.h>
2 #include "sh.h"
3
4 int main()
5 {
6 STACK stack;
7 stack_init(&stack);
8 int i=0;
9 for (;i<10;i++)
10 {
11 stack_push(&stack,i);
12 }
13 while(!stack_empty(&stack)){
14 printf("%d\n",stack_pop(&stack));
15 }
16
17 return 0;
18 }
数据结构笔记一
最新推荐文章于 2021-12-02 12:20:03 发布