数据结构之一对一(完结)
系统按照最大数据类型对齐;
为什么同一结构,在不同平台大小不同?
因为:
- 不同平台上相同类型所占(内存)字节不同
- 不同平台对齐方式不一样
#pragma pack(1)
:系统按照一个字节对齐。
struct Node
{
int a;
short b;
char c;
short d;
}
**小端存储:**低字节写在低地址里
联合体内所有变量共用同一块地址空间
全局变量和静态变量默认初始化为0
数据结构有几种结构?
集合,一对一,一对多,多对多。四种!
OneByOne(一对一)
---------------------------------------------------------------------------------------------
元素同属一个集合,前后元素有关系并单向
例如:线性表:
一个表里面元素a1到aN,a1没有直接前驱有且仅有一个直接后继,ai作为中间元素,有且仅有一个直接前驱
和一个直接后继,aN作为表的尾元素,没有直接后继,有且仅有一个直接前驱直接前驱也叫直接前件
线性表的两种储存结构
- 顺序储存→数组
- 链式储存→链表
递归和循环的优缺点
递归:代码简单,逻辑简单(便于阅读),但是函数跳转浪费时间,函数参数占用空间
循环:相对于递归,节约资源,但是每层循环逻辑必须弄清
stack(栈)
特性:先进后出,且只能操作栈顶
本质:也许是数组,也许是链表
常用栈:单向链表,头添加,头删除
八个基本操作
- Push 添加元素
- Pop 删除元素
- Init 初始化栈
- Clear 清空栈
- Deatroy 销毁栈
- GetCount 获得栈元素个数
- GetTop 得到栈顶
- IsEmpty 判断是否是空栈
#include<stdio.h>
#include<stdlib.h>typedef struct node1
{int nValue;struct node1 *pNext;
}MyStack;typedef struct node2
{MyStack *pTop;int nCount;
}Stack;//初始化
void s_Init(Stack **pStack)
{if(pStack == NULL)return;*pStack = (Stack*)malloc(sizeof(Stack));(*pStack)->pTop = NULL;(*pStack)->nCount = 0;
}//压栈
void s_Push(Stack *pStack,int nNum)
{MyStack *pTemp = NULL;if(pStack == NULL){printf("栈没啦!!!\n");return;}//开辟新节点装载值pTemp = (MyStack*)malloc(sizeof(MyStack));pTemp->nValue = nNum;pTemp->pNext = pStack->pTop;pStack->pTop = pTemp;pStack->nCount++;
}//出栈
int s_Pop(Stack *pStack)
{MyStack *pDel = NULL;int nNum;if(pStack == NULL || pStack->pTop == NULL)return -1;pDel = pStack->pTop;nNum = pDel->nValue;pStack->pTop = pStack->pTop->pNext;free(pDel);pDel = NULL;pStack->nCount--;return nNum;
}//清空
void s_Clear(Stack *pStack)
{if(pStack == NULL || pStack->pTop == NULL)return;while(pStack->nCount){s_Pop(pStack);}
}//销毁
void s_Destroy(Stack **pStack)
{s_Clear(*pStack);free(*pStack);*pStack = NULL;
}//获得栈内元素个数
int s_GetCount(Stack *pStack)
{if(pStack == NULL)return -1;return pStack->nCount;
}//获得栈顶
MyStack *s_GetTop(Stack *pStack)
{if(pStack == NULL)return NULL;return pStack->pTop;
}//是否为空栈
int s_IsEmpty(Stack *pStack)
{if(pStack == NULL)return -1;return (pStack->nCount)?0:1;
}int main()
{Stack *pStack = NULL;s_Init(&pStack);s_Push(pStack,1);s_Push(pStack,2);s_Push(pStack,3);s_Push(pStack,4);s_Push(pStack,5);printf("%d\n",s_Pop(pStack));printf("%d\n",s_Pop(pStack));printf("-------------------------------------------------\n");printf("%d\n",s_GetCount(pStack));s_Destroy(&pStack);s_Push(pStack,5);return 0;
}
***二级指针的使用:***一般是参数无中生有,和从有到无
递归相当于栈的实际应用
因为:解决大问题的方式与其子问题方式一致(定义)
斐波那契数列FIBONACCI
也叫***黄金分割数列***
#include<stdio.h.>
#include<stdlib.h>
int Fibonacci_1(int n)//迭代法
{if (n<=2){return 1;}return Fibonacci_1(n-1)+Fibonacci_1(n-2);
}
int Fibonacci_2(int n)
{int i = 3;int a = 1;int b = 1;int c = 0;if (n<=2){return 1;}for ( ;i <=n; i++){c = a+b;a = b;b = c;}return c;
}
int main()
{printf("%d\n",Fibonacci_1(10));printf("%d\n",Fibonacci_2(10));return 0;
}
四则运算
后缀表达式(逆波兰表示法)。
**中缀表示法:**例如:19+41*5-7/6,也叫表达式
转换规则
中缀转后缀(官方版)
借助辅助栈,遇到数字或字符直接打印,遇到符号(+ - * /),拿当前符号与栈顶元素进行优先级比较。如果当前元素优先级高直接入栈,如果当前元素优先级低,则直接出栈直到比当前元素优先级比它低的,如果遇到左括号无条件入栈,如果遇到右括号,将栈内元素依次出栈直到左括号停下来,如果没有元素,就将栈内元素全部拿出。
非官方版
所以运算加括号,将运算符放到括号后面。
后缀转中缀
遇到数字或字符直接进栈,遇到符号将栈顶元素下一个和栈顶元素构成表达式。
Queue
实际应用:打印机
特性:先进先出
#include<stdio.h>
#include<stdlib.h>typedef struct node3
{int nValue;struct node3 *pNext;
}MyQueue;typedef struct node4
{int nCount;MyQueue* pHead;MyQueue *pTail;
}Queue;void q_Init(Queue **pQueue)
{if(pQueue == NULL)return;*pQueue = (Queue*)malloc(sizeof(Queue));(*pQueue)->nCount = 0;(*pQueue)->pHead = NULL;(*pQueue)->pTail = NULL;
}void q_Push(Queue *pQueue,int nNum)
{MyQueue *pTemp = NULL;if(pQueue == NULL)return;pTemp = (MyQueue*)malloc(sizeof(MyQueue));pTemp->nValue = nNum;pTemp->pNext = NULL;if(pQueue->pHead == NULL){pQueue->pHead = pTemp;}else{pQueue->pTail->pNext = pTemp;}pQueue->pTail = pTemp;pQueue->nCount++;}
int q_Pop(Queue *pQueue)
{MyQueue *pDel = NULL;int nNum;if(pQueue == NULL || pQueue->pHead == NULL)return -1;pDel = pQueue->pHead;nNum = pDel->nValue;pQueue->pHead = pQueue->pHead->pNext;free(pDel);pDel = NULL;pQueue->nCount--;if(pQueue->nCount == 0){pQueue->pTail = NULL;}return nNum;
}int q_IsEmpty(Queue *pQueue)
{if(pQueue == NULL )return -1;return pQueue->nCount ? 0:1;
}
Queue To Stack
用两个Queue(队列)实现Stack(栈)
#include<stdio.h>
#include<stdlib.h>typedef struct node3
{int nValue;struct node3 *pNext;
}MyQueue;typedef struct node4
{int nCount;MyQueue* pHead;MyQueue *pTail;
}Queue;typedef struct node
{Queue *pQueue1;Queue *pQueue2;int nCount;
}Stack;void q_Init(Queue **pQueue)
{if(pQueue == NULL)return;*pQueue = (Queue*)malloc(sizeof(Queue));(*pQueue)->nCount = 0;(*pQueue)->pHead = NULL;(*pQueue)->pTail = NULL;
}void q_Push(Queue *pQueue,int nNum)
{MyQueue *pTemp = NULL;if(pQueue == NULL)return;pTemp = (MyQueue*)malloc(sizeof(MyQueue));pTemp->nValue = nNum;pTemp->pNext = NULL;if(pQueue->pHead == NULL){pQueue->pHead = pTemp;}else{pQueue->pTail->pNext = pTemp;}pQueue->pTail = pTemp;pQueue->nCount++;}int q_Pop(Queue *pQueue)
{MyQueue *pDel = NULL;int nNum;if(pQueue == NULL || pQueue->pHead == NULL)return -1;pDel = pQueue->pHead;nNum = pDel->nValue;pQueue->pHead = pQueue->pHead->pNext;free(pDel);pDel = NULL;pQueue->nCount--;if(pQueue->nCount == 0){pQueue->pTail = NULL;}return nNum;
}int q_IsEmpty(Queue *pQueue)
{if(pQueue == NULL )return -1;return pQueue->nCount ? 0:1;
}void s_Init(Stack **pStack)
{if(pStack == NULL)return;*pStack = (Stack*)malloc(sizeof(Stack));(*pStack)->nCount = 0;(*pStack)->pQueue1 = NULL;(*pStack)->pQueue2 = NULL;//初始化两个队列q_Init(&((*pStack)->pQueue1));q_Init(&((*pStack)->pQueue2));
}void s_Push(Stack *pStack,int nNum)
{MyQueue *pTemp = NULL;if(pStack == NULL || pStack->pQueue1 == NULL || pStack->pQueue2 == NULL)return;//将数值放入非空队列if(!q_IsEmpty(pStack->pQueue1)){q_Push(pStack->pQueue1,nNum);}else{q_Push(pStack->pQueue2,nNum);}
}int s_Pop(Stack *pStack)
{int nNum;if(pStack == NULL || (pStack->pQueue1 == NULL && pStack->pQueue2 == NULL))return -1;//检测非空队列if(!q_IsEmpty(pStack->pQueue1)){//将队列元素依次放入空队列里 直到剩一个的时候停下来while(pStack->pQueue1->nCount != 1){q_Push(pStack->pQueue2, q_Pop(pStack->pQueue1) );}nNum = q_Pop(pStack->pQueue1);}else{//将队列元素依次放入空队列里 直到剩一个的时候停下来while(pStack->pQueue2->nCount != 1){q_Push(pStack->pQueue1, q_Pop(pStack->pQueue2) );}nNum = q_Pop(pStack->pQueue2);}return nNum;
}
Stack To Queue
用两个栈实现队列
#include<stdio.h>
#include<stdlib.h>
typedef struct node1
{int nValue;struct node1 *pNext;
}MyStack;typedef struct node2
{MyStack *pTop;int nCount;
}Stack;
typedef struct node3
{Stack *Mystack_1;Stack *Mystack_2;int nCount;
}MyQueue;//初始化
void s_Init(Stack **pStack)
{if(pStack == NULL)return;*pStack = (Stack*)malloc(sizeof(Stack));(*pStack)->pTop = NULL;(*pStack)->nCount = 0;
}//压栈
void s_Push(Stack *pStack,int nNum)
{MyStack *pTemp = NULL;if(pStack == NULL){printf("栈没啦!!!\n");return;}//开辟新节点装载值pTemp = (MyStack*)malloc(sizeof(MyStack));pTemp->nValue = nNum;pTemp->pNext = pStack->pTop;pStack->pTop = pTemp;pStack->nCount++;
}//出栈
int s_Pop(Stack *pStack)
{MyStack *pDel = NULL;int nNum;if(pStack == NULL || pStack->pTop == NULL)return -1;pDel = pStack->pTop;nNum = pDel->nValue;pStack->pTop = pStack->pTop->pNext;free(pDel);pDel = NULL;pStack->nCount--;return nNum;
}
//是否为空栈
int s_IsEmpty(Stack *pStack)
{if(pStack == NULL)return -1;return (pStack->nCount)?0:1;
}
void q_Init(MyQueue **queue)
{if (queue == NULL )return;(*queue) = (MyQueue*)malloc(sizeof(MyQueue));(*queue)->Mystack_1 = NULL;(*queue)->Mystack_2 = NULL;s_Init(&(*queue)->Mystack_2);s_Init(&(*queue)->Mystack_1);(*queue)->nCount = 0;
}
void q_Push(MyQueue *queue,int nValue)
{s_Push(queue->Mystack_2,nValue);return;}
int q_Pop(MyQueue *queue)
{int num;if (s_IsEmpty((queue)->Mystack_1)){while (queue->Mystack_2->nCount != 1){s_Push((queue)->Mystack_1,s_Pop((queue)->Mystack_2));}num = s_Pop((queue)->Mystack_2);while (queue->Mystack_1->nCount != 0){s_Push((queue)->Mystack_2,s_Pop((queue)->Mystack_1));}}return num;}
数据结构之一对一(完结)相关推荐
- 数据结构: 是什么?
数据结构是什么?数据和结构有什么关系? 数据结构首先要定义两个东西,一个是数据,一个是结构. 数据是一组有意义的信息.把数据作为信息单元. 结构,就是信息单元和信息单元之间的构成关系. 构成关系以最抽 ...
- Java数据结构之二叉树及其源码实现
树 我们的数据结构包含一对一.一对多.多对多的存储关系. 我们常用的一对一的数据结构:数组以及链表:一对多的数据结构:树:多对多:图. 本文主要介绍树的常用结构 二叉树. 二叉树 二叉树基本特点 至多 ...
- bat脚本保存dir结果_Tomcat的启停脚本源码解析
作者 | 程序员自由之路 来源 | cnblogs.com/54chensongxia/p/13234398.html Tomcat的启停脚本源码解析 Tomcat是一款我们平时开发过程中最常用到的S ...
- python 数据结构篇
在众多编程语言里,数据结构与算法都可以说是至关重要的基础.但是对于python而言,因为其本身就是用C实现的,其速度和效率本身较低,因而pyhon没有像其他语言那样那么重视数据结构与算法(python ...
- 35岁找工作,这个最重要
最近一些35岁左右的中年失业朋友找我聊,我发现他们找工作的方式和年轻人并没有什么不同,还是通过网络APP进行海投. 如果你刚开始工作的时候,通过这种方式去找工作,无可厚非,但如果工作很久了,还通过这种 ...
- <<大话数据结构>>之完结感言
完结感言 <<大话数据结构>>这本书是我至今为止,算得上我看过的最完整的一本书了.大话数据结构学习到今天,终于把看中的知识看了一遍,并且把对日后可能用到的知识加以总结.其实,我 ...
- 数据结构浙江大学 全部思考题+每周练习答案(已完结)
全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案 MOOC上浙江大学陈越和何钦铭老师的数据结构课程很不错,通俗易懂,每周习题还都有点挑战性,这里打算将所有的题进行一下汇 ...
- 第二章 数据结构 【完结】
栈那节表达式求值,并查集食物链还没做 堆,哈希表不熟,比赛的时候也很少遇到,故没有经常的练习. 目录 单链表[静态] 双链表[静态] 栈 队列 单调栈 单调队列 KMP Trie 并查集 堆 哈希表 ...
- 数据结构与算法总结(完结)
极客时间算法学习之后开始跟着花花酱刷题.大概从4月份开始的.从今天开始(2020-8-24)开始做总结,复习一下已经刷过的题目.到目前为止leetcode刷题323道. 2020/8/24 完成题目整 ...
最新文章
- 如何检查字符串是否包含特定单词?
- 【Python实战】Django建站笔记
- 【转载】VMware安装CentOS7时忘记装图形化界面——如何补装GNOME
- 《概率论与数理统计习题全解指南》中的“计算机得”
- The import com.sun.tools cannot be resolved
- 怎么看电脑的hdmi是输出还是输入_高清hdmi矩阵切换器4进4出音视频方案介绍景阳华泰科技...
- re.DOTALL --编写多行模式的正则表达式
- 2021教师资格证中学科目二简答汇总分享
- Vue2 使用Volar 报错:<template v-for> key should be placed on the <template> tag
- 互联网女皇报告:拼多多美团崛起,支付宝微信同台竞技!
- 删除计算机网络无用设备,如何删除我的电脑/计算机中无效的设备和驱动器图标...
- 163 镜像源 linux,网易163的Ubuntu apt镜像源
- IAR调试stm8的优化设置
- Python非线性拟合笔记
- C语言迷宫如何实现多个关卡,c语言实现迷宫问题#仅供借鉴
- 出新书了!| 赠书啦,免费包邮
- win10计算机拨号连接,Win10设置电脑开机自动连接宽带的方法
- CentOS7部署网盘网站
- java编写point类line类_定义一个点类Point,有横坐标x和纵坐标y,定义构造
- 影像测量—摄影测量和RTK原理