数据结构中的栈和递归以及队列

来源:互联网 发布:寒武纪年手机版软件 编辑:程序博客网 时间:2024/05/13 19:59

栈定义:是限定仅在表尾进行插入或删除操作的线性表。表尾 称为栈顶,表头称为栈底,不含元素的空表称为空栈(记得以前学汇编语言的时候,经常讲压栈、出栈当是就不明白,现在算是明白了一点了,栈并不是能把所有不同的东西都压入的,我猜测可能有多种栈,按元素类型来划分,比如有函数栈,变量栈等)。
栈表示和实现:栈也是像线性表一样可以用数组或者链表来实现,大多采用链表。栈的操作就是在添加到链表尾和从链表尾取出。

C语言实现的栈结构

#include <stdio.h>#include <stdlib.h>typedef int NodeType;  //重定义一下int这个数据类型,作为节点数据域类型struct LinkList{    NodeType i;   //数据域,这里可以使用泛型代替,这样就可以对泛型数据操作了    struct LinkList* pLast; //指向上一个节点的指针,因为我们是在表尾操作,所以存储前一个的指针;};struct Stack{    int size; //栈中元素个数    struct LinkList* bottomLink;  //栈结构中的栈底元素    struct LinkList* topLink;   //栈结构中的栈顶元素};void initStack(struct Stack *s) //初始化栈结构{    struct LinkList l;    l.i=0;    l.pLast=NULL;    s->size=0;    s->bottomLink=&l;    s->topLink=s->bottomLink;}//压栈void push(NodeType node,struct Stack *s){    struct LinkList *m=(struct LinkList *)malloc(sizeof(struct LinkList));  //首先把节点元素给穿件出来    m->i=node;     //把节点元素中的数据域赋值    m->pLast=s->topLink;  //把节点元素中指向上一个节点的指针改为栈顶指针    s->size++;      //栈元素增加    s->topLink=m; //更新栈顶指针}void show(struct Stack *s){    struct LinkList* m=s->topLink; //先取到栈顶元素    while(m->pLast!=NULL)    //判断是否到达栈底    {        printf("%d  |",m->i);  //输出单前节点的元素        m=m->pLast;            //把m指向上一个节点    }    printf("\n");}int count(struct Stack *s){    return s->size;  //统计元素个数,用size属性 也是可以的}//出栈int pop(struct Stack *s)    //对于栈来说,移除肯定是指移除栈底元素,不然就不是栈了{    struct LinkList* m=s->topLink;    //获取栈顶元素    s->topLink=m->pLast;     //把上一个节点的指针赋给栈顶元素    s->size--;   //更改栈中元素个数    free(m);  //释放开始的栈顶元素}int main(void){    struct Stack s; //新建一个栈引用,还没有分配内存    initStack(&s);    int i=10;    for(i;i<20;i++){        push(i,&s);    }    pop(&s);    pop(&s);    show(&s);    printf("%d",s.size);    return -1;}

结果:
这里写图片描述

栈结构的应用:进制之间的转换

#define BINARY 2 //二进制数#define OCTONARY 8 //八进制#define DECIMAL 10 //十进制#define HEXAD 16//十六进制
void conversion(unsigned n,int d){    struct Stack s1; //新建一个栈引用,还没有分配内存    initStack(&s1);    int m=0;    switch(d)    {    case BINARY:        m=BINARY;        break;    case OCTONARY:        m=OCTONARY;        break;    case DECIMAL:        m=DECIMAL;        break;    case HEXAD:        m=HEXAD;        break;    default:        printf("你输入的进制不合法!");        exit(-1);        break;    }    while(n)    {        push(n%m,&s1);        n=n/m;    }    while(isEmpty(&s1))    {        int i=pop(&s1);        if(i<9){            printf("%d",i);        }else{            printf("%c",i+55); //应对十六进制的,大于9的数就使用字母表示        }    }    switch(d)    {    case BINARY:        printf(" b\n");        break;    case OCTONARY:        printf(" O\n");        break;    case DECIMAL:        printf(" \n");        break;    case HEXAD:        printf(" H\n");        break;    default:        printf("你输入的进制不合法!");        exit(-1);        break;    }}
//用法,直接传入需要转换的数和要被转换的进制数就行,这个必须是十进制转换为其他进制conversion(1348,BINARY);

这里写图片描述

递归:自身调用自身的函数,或者形成循环调用的函数

汉诺塔问题使用递归求解
#include <stdio.h>long c=0;void move(char x,int n,char z){    //第n个圆盘从塔座x搬到塔座z    c++;}void hannoi(int n,char x,char y,char z){    if(n==1){       move(x,1,z);    }else{        hannoi(n-1,x,z,y);        move(x,n,z);        hannoi(n-1,y,x,z);    }}int main(void){    int n=0;    printf("请输入圆盘数:");    scanf("%d",&n);    hannoi(n,'x','y','z');    printf("%ld",c);    return -1;}

队列

#include <stdio.h>typedef int QElemType;struct Node{    QElemType e;    struct Node* pNext;};struct Queue{    int zise;    struct Node* front;    struct Node* rear;};void init(struct Queue *q){    struct Node n;    n.e=0;    n.pNext=NULL;    q->zise=0;   //一定要记住初始化,不然这个size值就不是从0开始计数    q->front=&n;    q->rear=&n;}/*    在表尾添加,*/void push(QElemType e,struct Queue *q){    struct Node* n=(struct Node*)malloc(sizeof(struct Node));  //先生成一个节点    n->e=e;   //把这个节点数据域赋值    n->pNext=NULL; //把这个节点指向下一个节点的值赋值为NULL    q->rear->pNext=n;  //把尾节点的指向下一个节点的值赋值为新节点    q->rear=n;   //把当前节点赋值为尾节点    q->zise++;   //节点元素增加}void show(struct Queue *q){    struct Node* n=q->front;    while(n->pNext!=NULL)    {        n=n->pNext;        printf("%d ",n->e);    }    printf("\n");}/*    从表头弹出*/int pop(struct Queue *q){    struct Node* n=q->front; //获取表头元素    int i=n->e; //先把节点中的数据拿出来    if(n->pNext==NULL)    {        printf("队列中没有元素!");        exit(-1);    }    struct Node* m=n->pNext; //把表头之后的那个元素指针拿到    q->front=m;    free(n);//释放节点内存    q->zise--;    return i;}int main(void){    struct Queue q;    init(&q);    int i=90;    for(i;i<100;i++)    {        push(i,&q);    }    pop(&q);    pop(&q);    pop(&q);    show(&q);    printf("%d",q.zise);    return -1;}

结果:
这里写图片描述

0 0
原创粉丝点击