目录
一、栈
栈是一种特殊的线性表,只允许在固定一端插入数据和删除数据,数据插入和删除的一端叫做栈顶,另外一端叫做栈底。
二、实现思路
即可以使用链表实现,链表最好使用双向链表
也可以使用数组实现
如果一定要使用单链表,两种方式:
1、头节点做栈底,尾节点做栈顶,入栈没问题,但是出栈就会出问题,因为还需要找到前一个位置,相当于尾删,单链表不支持随机访问,必须定义一个指针记录其前一个位置,不简洁,不方便,啰嗦,难受
2、把头节点当作栈顶,相当于头插,新节点作为栈顶,这就避免了找上述麻烦
那么选谁呢?整体来说,数组的效率更高
三、基本操作
栈的插入叫做压栈,删除叫做出栈
即入数据在栈顶,出数据也在栈顶
栈的实现,通俗而言就是进入和删除的方式比较特殊,仅此而已
1、初始化
typedef struct Stack{
StDateType *a;
int capacity;
int top;
}ST;
ST st;
st->date =malloc();//初始给多少自己定义
st->capacity = 4;
st->top = 0/-1
如果top是-1,那么每一次入栈,top++,指向这个数据位置本身
如果top是0,那么每一次入栈,top++,指向这个数据的下一个
都可以,只是略有差距。选择什么,玩什么
2、销毁栈
free(st->date);
st->top=st->capacity = 0;
3、出栈
assert(st);
assert(st->top > 0)
st->top--;
//注意,出栈将元素置0是不科学的,如果该元素本身就是0呢?
//或者说,数据元素不是int类型,而是double、或者结构体呢?就不合适了,对于代码的容错不行
//而这里直接st->top--,意思是现在没有删除,但是我的栈顶元素却已经指向了下一个,不管你栈顶后面的数据。因为,我访问的数据只能是栈底到栈顶,其他数据不在我的范畴内,我不管
而且后面要是有数据进栈,就会进行覆盖,不影响
4、进栈
st->date[st->top] = insert;
st-top++;
//增容判断
StDatetype *tmp = (StDateType*)realloc(st->date,sizeof(st->capacity*2));
if(tmp = NULL)
{
exit(-1);
或者:
assert(tmp);
}
else{
st->date = tmp;
st->capacity *=2;
}
5、返回栈顶:
return st->date[st->top -1];
栈使用数组实现,使用数组要注意开头索引是0
6、判空函数
返回值为布尔值,return st->top ==0;
以下是整体实现代码:
写代码,似乎最核心的就是一个思路的问题,而不是语言。语言就是一个描述方式,用语言将我们的思路,我们想要表达意思表达出来。
至于不会写,我想不是思路的问题,而是对语言工具的不熟悉。即我认为我当前最缺乏的不是对思路算法的理解,而是对语言的理解已经熟悉程度不够,也就是说当前最缺乏的是代码的积累不够,这才导致写代码时磕磕绊绊。要多写