数据结构笔记一

		
数据结构: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 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值