算法导论9:栈的链表实现 2016.1.9

一直想做一个链表实现的栈,今天终于实现了。确实比数组要难多了,打了很久,很长时间花在了想象上(指针调试比较复杂。。)

但是链表实现有一个最大的好处,就是动态分配内存,所以一般不会出现栈顶溢出的问题。

值得一提的是代码中比昨天的多了一个build函数。建立一个新栈。那么init函数,还是初始化一个栈。昨天用数组写的时候这两个函数是一样的。但是用链表之后才发现两者还是有区别。一个是从无到有,一个是从有到无。只不过数组的时候本来都有,不涉及自己申请空间的问题,所以两个的操作可以相同,但是到了链表,内存要自己申请和释放,这两个函数也就不一样了。不过写完这个栈,我对c++里封装的集合对象有了一点想法,不知道和我想的是不是一样。等假期看c++primer的时候看一下。

下面是代码:

#include<stdio.h>
#include<stdlib.h>

typedef struct _node{
    int num;
    struct _node *next;
}node;

struct stack {
    node * bottom;
    node * top;
}s;

void build(struct stack &S)
{
    S.bottom=(node *)malloc(sizeof(node));
    S.bottom->next=NULL;
    S.top=(node *)malloc(sizeof(node));
    S.top->next=S.bottom;
}

int sempty(struct stack &S)
{
    if ((S.top)->next==S.bottom) return 1;
    else return 0;
}

int pop(struct stack &S)
{
    if (sempty(S)) {
        printf("栈为空,弹出失败!\n");
    }
    else {
        node *p;
        p=S.top;
        S.top=(S.top)->next;
        int k=p->num;
        free(p);
        return k;
    }
}

void init(struct stack &S)
{

    while (!sempty(S)) {
        pop(S);
    }
}

void push(struct stack &S,int n)
{
    node *p;
    p=(node *)malloc(sizeof(node));
    p->num=n;
    p->next=S.top;
    S.top=p;
}

void showstack(struct stack S)
{
    while ((S.top)->next!=S.bottom){
        int k=(S.top)->num;
        S.top=(S.top)->next;
        printf("|%d|\n",k);
    }
    printf("| |\n");
    printf(" - \n");
}

int main()
{
    printf("1:初始化栈;2:入栈;3:出栈;4:退出。\n");
    build(s);
    int n;
    while (1) {
        int k;
        scanf("%d",&k);
        switch(k) {
            case 1:init(s); break;
            case 2:scanf("%d",&n); push(s,n); break;
            case 3:pop(s); break;
            case 4:return 0;
        }
        showstack(s);
    }
    return 0;
}
时间: 2024-08-05 15:21:03

算法导论9:栈的链表实现 2016.1.9的相关文章

算法导论2:几个习题 2016.1.2

一.在归并排序中对小数组采用插入排序(放在上一篇里了): 二.冒泡排序 冒泡排序效率几乎是所有排序里最低的,但却很流行,就是因为它的变成复杂度也是最低的.大多数时候,效率还不及插入排序,其实冒泡排序.插入排序.选择排序基本上效果是差不多的(这个效果不是功能..功能上讲肯定差不多啊都是排序),只是过程略有区别.既然写到这里,就自己总结一下三者吧. 1.插入排序——摸扑克牌的过程 假定前一个是有序的,把第二个插进它应当在的位置,那么前两个就是有序的了,把第三个插进它应当在的位置,那么前三个就是有序的

算法导论中对二叉树链表中 Delete 函数的实现

上一篇博客中对 Delete 函数的实现是根据被删除节点子节点的子节点个数, 分为无子节点, 一个子节点和两个子节点的情况分别考虑的. 而这次的代码是根据算法导论的实现用 C++ 直译过来的, 代码如下: void BinarySearchTree::Delete (const int32_t& value) { auto node = Search (value); if (node == nullptr) { cerr << "There is no such value

算法导论14:树形数据结构——二叉树 2016.1.14

从上一篇开始应该就能感受到,其实既然环形的数据结构可以做出来,各种形状的数据结构都可以做出来,只要设计好节点的属性和节点之间的关系就行了. 用指针的实现会更加好理解,但是编程复杂度会相对更高,用数组实现,编程复杂度相对低,但是相对不那么直观.所以两种方式灵活选择吧.(不过用c++很多内置对象就可以解决很多问题) ……待更新

算法导论之链表

一.概念 (1)数组的线性序是由数组的下标决定的,链表中的顺序是由各对象中的指针所决定的 (2)链表结点结构 node *prev; node *next; int key; (3)链表结点 node *head; node *nil;//哨兵 (4)对链表的操作 LIST-SEARCH(L, k) LIST-INSERT(L, x) LIST-DELETE(L, x) (5)哨兵是个哑对象,可以简化边界条件 二.代码 (1)没有哨兵的情况 [cpp] view plain copy print

算法导论10:栈链表的简化、队列的数组实现 2016.1.10

新年的前十天做了比较有意义的事情就是坚持每天写博客,明天就开始期末考试了,所以等假期再继续学习. 把昨天提到的S.bottom简化之后又改了栈的链表.代码如下(已折叠): #include<stdio.h> #include<stdlib.h> typedef struct _node{ int num; struct _node *next; }node; node *s; void build(node *&S) { s=(node *)malloc(sizeof(no

算法导论8:数据结构——栈 2016.1.8

栈在暑假的时候接触过了,当时还写了个计算器,用的中缀表达式后缀表达式的栈操作. http://www.cnblogs.com/itlqs/p/4749998.html 今天按照算法导论上的讲解规范了一下代码.主要是栈的初始化.判断空栈.入栈.出栈.遍历栈. #include<stdio.h> #define MAXTOP 10 struct _stack { int top; int num[MAXTOP+1]; }s; void init(struct _stack &S) { S.

【算法导论学习-23】两个单链表(single linked)求交点

问题:A.B两个单链表如果有交点,返回第一个交点在A中的位置(链表头结点位置为0). 分析:A.B如果有交点,交点的后继一定也是交点,所以一定是Y型相交,所以算法的思想如下 1)  求得A.B的长度,比如ALength,Blength 2)  判断ALength,Blength谁大,比如Alength>Blength 3)  Alength移动到Alength-Blength的位置,开始判断每个节点是否相等,相等则退出. 以本博客中"[算法导论学习-20]单链表(single linked

算法导论6:排序小结和最值取法 2016.1.6

今天想做测试各个排序算法运行时间比较的程序,来对这几天学的排序算法小结一下.所以我先生成了1000000个1~150之间的随机数存到文件里.然后做了一个测试运行时间的程序.想看一下结构.但是结果效果并不太好.实践中,自己做的qsort函数和mergesort函数并没有理想中的那么快. 结果是这样:(可能并不准确,但却是是运行结果) 库函数快速排序:0.139000 seconds自制快速排序:0.375000 seconds归并排序:0.358000 seconds堆排序:0.525000 se

算法导论5:基数排序 2016.1.5

今天的这个比较神奇,是一个线性复杂度的排序算法O(n),算法导论在这一部分先证明了比较排序的复杂度下界是nlgn,所以基数排序不是基于比较的排序. 其实这种比较方法我们应该都接触过.假设输入的数都是三位以下的数(当然其他位数也可以,类比一下,这里就假设是三位数.两位数.一位数),那么只需要大致3n的复杂度就可以排好序.过程是这样: 先设置辅助空间t[0..9][n] 然后扫第一遍n个数,个位是几就放在t[几]那一行.然后扫一遍t数组,按顺序放回原数组中 然后扫第二遍n个数,十位是几就放在t[几]