数据结构的概念、仓库
数据结构与算法
数据结构研讨程序里怎么运用存储区寄存数字,算法研讨处理一些常见问题的通用办法。数字之间的联络能够从两个彻底不同的视点描绘。
逻辑联络(逻辑结构)描绘数字之间与计算机无关的联络;物理联络(物理结构)描绘寄存数字的存储区之间的联络。
逻辑结构
1.调集结构:一切的数字能够被看做一个全体
2.线性结构:假如能够用一条有次序的线把一切数字串起来则数字之间是线性结构的
3.树状结构:一切数据都是从一个数据向同一个方向扩展出来的,任何数字能够拓展出多个其他数字
4.网状结构:任何两个数字之间都能够有直接的联络,一切数字之间的联络没有一致的方向
物理结构
1.次序结构:一切存储区在内存里接连摆放,数组和动态分配内存都是次序结构的比如,次序结构里每个存储区都有一个编号,能够直接经过编号找到对应的存储区。次序结构能够不经过其他存储区直接找到需求的存储区,这种才能叫随机拜访才能。次序结构里的存储区个数很难调整,简单形成内存糟蹋。
2.链式结构:由多个彼此独立的存储区构成,任何两个存储区之间能够用指针衔接,链式物理结构里每个存储区都是一个结构体类型的存储区,他们叫做节点,单向线性链式物理结构中任何两个节点之间都有前后次序(每个节点里只需求包括一个指针)。单向线性链式物理结构里最终一个节点里的指针有必要是空指针。能够在单向线性链式物理组织中最前面的节点前再添加一个节点,这个节点叫头节点。能够在单向线性链式物理结构中最终面的节点后再添加一个节点,这个节点叫尾节点。
链式物理结构不支持随机拜访才能,链式物理结构合适进行刺进或删去操作,链式物理结构里的节点个数能够随时调整,
/*
*
*链式物理结构固定代码
*
* */
#include<stdio.h>
typedef struct node {
int num;
struct node *p_next;
} node;
int main (){
node node1 = {10}, node2 = {20}, node3 = {30},head = {0}, tail = {0};
node *p_node = NULL;
head.p_next = &node1;
node1.p_next = &node2;
node2.p_next = &node3;
node3.p_next = &tail;
/*
*p_node指针循环变量会从头节点开端
*向后顺次绑缚每个节点,直到最终一个有用节点停止
* */
for (p_node = &head;p_node != &tail;p_node = p_node->p_next){
/*
*以下三个指针和三个相邻节点绑缚
* 其间p_first指针绑缚的节点在最前面
*p_last指针绑缚的节点在最终
*p_mid指针绑缚的节点在中心
*p_mid指针在循环过程中从第一个有用节点一向绑缚到尾节点
* */
node *p_first = p_node;
node *p_mid = p_first->p_next;
node *p_last = p_mid->p_next;
if (p_mid != &tail){
printf("%d ",p_mid->num);
}
}
printf("\n");
return 0;
}
刺进删去操作
/*
*
*链式结构
*
* */
#include<stdio.h>
typedef struct node {
int num;
struct node *p_next;
} node;
int main (){
node node1 = {10}, node2 = {20}, node3 = {30},head = {0}, tail = {0};
node node4 = {15};
node *p_node = NULL;
head.p_next = &node1;
node1.p_next = &node2;
node2.p_next = &node3;
node3.p_next = &tail;
/*
*p_node指针循环变量会从头节点开端
*向后顺次绑缚每个节点,直到最终一个有用节点停止
*
* */
for (p_node = &head;p_node != &tail;p_node = p_node->p_next){
/*
*以下三个指针和三个相邻节点绑缚
* 其间p_first指针绑缚的节点在最前面
*p_last指针绑缚的节点在最终
*p_mid指针绑缚的节点在中心
*p_mid指针在循环过程中从第一个有用节点一向绑缚到尾节点
*
* */
node *p_first = p_node;
node *p_mid = p_first->p_next;
node *p_last = p_mid->p_next;
if (p_mid != &tail){
printf("%d ",p_mid->num);
}
}
printf("\n");
/*
*在链式结构里
*删去数据
* */
for (p_node = &head;p_node != &tail;p_node = p_node->p_next){
node *p_first = p_node;
node *p_mid = p_first->p_next;
node *p_last = p_mid->p_next;
if (p_mid != &tail && p_mid->num == 20){
p_first->p_next = p_last;
break;
}
}
/*
*链式结构刺进数据
*并确保排序从小到大
* */
for (p_node = &head;p_node != &tail;p_node = p_node->p_next){
node *p_first = p_node;
node *p_mid = p_first->p_next;
node *p_last = p_mid->p_next;
if (p_mid == &tail || p_mid->num > node4.num){
p_first->p_next = &node4;
node4.p_next = p_mid;
break;
}
}
for (p_node = &head;p_node != &tail;p_node = p_node->p_next){
node *p_first = p_node;
node *p_mid = p_first->p_next;
node *p_last = p_mid->p_next;
if (p_mid != &tail){
printf("%d ",p_mid->num);
}
}
printf("\n");
return 0;
}
数据结构
数据结构由一组存储区和相关的办理函数构成,这些函数供给了对存储区的运用办法,程序里的其他句子都只能经过这些函数运用这些存储区。
栈
栈是一种数据结构,栈能够用来寄存数字,栈里的数字有前后次序,先进入栈的数字在前,后进入栈的数字在后,每次只能从栈里取得一个数字,这个数字有必要是最终一个放进去的数字,这种运用数字的办法叫后进先出。
push和pop
编写栈的时分需求供给一个函数用来向栈里参加数字,这个函数称号一般叫push,编写栈的时分需求供给一个函数用来从栈里取得数字,这个函数称号一般叫pop。
栈操练:编写程序从键盘得到多个非负整数,把他们倒序显现在屏幕上,要求用栈完结。
/*
*栈演示主函数
* */
#include<stdio.h>
#include"1stack.h"
int main (){
int num = 0;
stack stk = {0};
stack_init(&stk);
while (1){
printf("请输入一个数字:");
scanf("%d",&num);
if (num < 0){
break;
}
if (!stack_push(&stk,num)){
break;
}
}
while (1){
if (!stack_pop(&stk,&num)){
break;
}
printf("%d ",num);
}
printf("\n");
stack_deinit(&stk);
return 0;
}
/*
*栈演示头文件
* */
#ifndef _1STACK_H_
#define _1STACK_H_
typedef struct {
int buf[SIZE];
int qty;
} stack;
//栈初始化函数
void stack_init (stack *);
//栈整理函数
void stack_deinit (stack *);
//计算栈里有用数字个数
int stack_size (const stack *);
//判别栈是否现已满了
int stack_full (const stack *);
//判别栈是否为空
int stack_empty (const stack *);
//向栈里参加数字的函数
int stack_push (stack *,int);
//从栈里取得数字的函数(从栈里删去数字)
int stack_pop (stack *,int *);
//从栈里取得数字的函数(不会删去数字)
int stack_top (const stack *,int *);
#endif //_1STACK_H_
/*
*栈演示源文件
* */
#include"1stack.h"
//栈初始化函数
void stack_init (stack *p_stack){
p_stack->qty = 0;
}
//栈整理函数
void stack_deinit (stack *p_stack){
p_stack->qty = 0;
}
//计算栈里有用数字个数
int stack_size (const stack *p_stack){
return p_stack->qty;
}
//判别栈是否现已满了
int stack_full (const stack *p_stack){
return p_stack->qty >= SIZE;
}
//判别栈是否为空
int stack_empty (const stack *p_stack){
return !(p_stack->qty);
}
//向栈里参加数字的函数
int stack_push (stack *p_stack,int num){
if (p_stack->qty >= SIZE){
return 0;
}
p_stack->buf[p_stack->qty] = num;
p_stack->qty++;
return 1;
}
//从栈里取得数字的函数(从栈里删去数字)
int stack_pop (stack *p_stack,int *p_num){
if (!(p_stack->qty)){
return 0;
}
*p_num = p_stack->buf[p_stack->qty - 1];
p_stack->qty--;
return 1;
}
//从栈里取得数字的函数(不会删去数字)
int stack_top (const stack *p_stack,int *p_num){
if (!(p_stack->qty)){
return 0;
}
*p_num = p_stack->buf[p_stack->qty - 1];
return 1;
}
阐明:程序履行后,依据数据输入非负数,数据输入完结时,以负数完毕输入。