当前位置:   article > 正文

数据结构DAY3--栈与队列

数据结构DAY3--栈与队列

栈:

是一种只能从一端操作的表,规则为先进后出

主要操作步骤为:1.建立相关结构体 2.建立栈 3.增加栈 4.获得栈顶值 5.删除 6.修改 7.销毁 

1.建立两个结构体

一个为链栈,一个为结点,链栈包括栈头(指针)和栈个数,结点包括数据和指向下一个栈的指针

  1. typedef struct node
  2. {
  3. int data;
  4. struct node *pnext;
  5. }STACK_NODE;
  6. typedef struct stack
  7. {
  8. STACK_NODE *ptop;
  9. int clen;
  10. }STACK_LIST;
2.建立栈

首先要建立一个链栈,首先用链栈结构体定义一个大小为结构体大小的指针,使其栈顶指向空,栈个数初始化为0,然后将其返回。

  1. STACK_LIST *create_link_stack()
  2. {
  3. STACK_LIST *pstack = malloc(sizeof(STACK_LIST));
  4. if (NULL == pstack)
  5. {
  6. perror("fail malloc");
  7. return NULL;
  8. }
  9. pstack->ptop = NULL;
  10. pstack->clen = 0;
  11. return pstack;
  12. }
3.增加栈

首先建立结点,用结点结构体定义一个大小为结构体大小的指针,使其数据域为输入数据,结点的后驱指针指向空,然后将其返回,返回后,使结点的后驱等于栈链的栈顶,栈链的栈顶等于结点,栈个数加1,一个栈就建立好了。

  1. STACK_NODE *create_node(DATA_TYPE data)
  2. {
  3. STACK_NODE *pnode = malloc(sizeof(STACK_NODE));
  4. if (NULL == pnode)
  5. {
  6. perror("fail malloc");
  7. return NULL;
  8. }
  9. pnode->data = data;
  10. pnode->pnext = NULL;
  11. return pnode;
  12. }
  13. int push_stack(STACK_LIST *pstack, STACK_NODE *pnode)
  14. {
  15. if (NULL == pstack || NULL == pnode)
  16. {
  17. return -1;
  18. }
  19. pnode->pnext = pstack->ptop;
  20. pstack->ptop = pnode;
  21. pstack->clen++;
  22. return 0;
  23. }
4.获得栈顶值:

输入一个指针,以便能从函数中获取数据,使该指针等于链栈的顶的数据域的值即可。

5.删除(出栈):

其与直接删除不同,其在删除时还会获得删除处的值,所以也要输入一个指针获得数据,首先用结点结构体定义一个结点,使该结点等于栈顶,再使栈顶等于结点的后驱(相当于删除了一个),此时再使指针等于此时栈顶的数据域的值。最后使用free释放结点, 栈个数减一。

  1. int pop_stack(STACK_LIST *pstack, DATA_TYPE *pdata)
  2. {
  3. if (NULL == pstack)
  4. {
  5. return -1;
  6. }
  7. if (is_empty_stack(pstack))
  8. {
  9. return -1;
  10. }
  11. STACK_NODE *pnode = pstack->ptop;
  12. pstack->ptop = pnode->pnext;
  13. if (pdata != NULL)
  14. {
  15. *pdata = pnode->data;
  16. }
  17. free(pnode);
  18. pstack->clen--;
  19. return 0;
  20. }
6.销毁 :

循环出栈,直到链栈头指向空,出栈时不用获取数据。最后再释放链栈空间

  1. void clear_stack(STACK_LIST *pstack)
  2. {
  3. while (!is_empty_stack(pstack))
  4. {
  5. pop_stack(pstack, NULL);
  6. }
  7. free(pstack);
  8. }

队列:

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

主要操作步骤为:初始化队列,入队,出队,遍历,销毁队列

初始化队列:

同链表与栈,首先建立两个结构体,一个为队列表头,包括指向对头的指针和指向对尾的指针,以及队列结点的个数。另一个为队列结点,包括数据域以及指向下个结点的指针。

  1. typedef struct node
  2. {
  3. DATA_TYPE data;
  4. struct node *pnext;
  5. }QUE_NODE;
  6. typedef struct que
  7. {
  8. QUE_NODE *pfront;
  9. QUE_NODE *prear;
  10. int clen;
  11. }QUE_LIST;
入队操作:

首先创建队列表头,用表头结构体定义一个大小为结构体大小的指针,使队头队尾都指向空,队列结点个数尾为0,然后将其返回:

  1. QUE_LIST *create_link_queue()
  2. {
  3. QUE_LIST *pque = malloc(sizeof(QUE_LIST));
  4. if (NULL == pque)
  5. {
  6. perror("fail malloc");
  7. return NULL;
  8. }
  9. pque->pfront = NULL;
  10. pque->prear = NULL;
  11. pque->clen = 0;
  12. return pque;
  13. }

其次创建结点,用结点结构体定义一个大小为结构体大小的指针,后驱结点指向空,数据域为输入的数据,并将其返回。

  1. QUE_NODE *create_node(DATA_TYPE data)
  2. {
  3. QUE_NODE *pnode = malloc(sizeof(QUE_NODE));
  4. if (NULL == pnode)
  5. {
  6. perror("fail malloc");
  7. return NULL;
  8. }
  9. pnode->data = data;
  10. pnode->pnext = NULL;
  11. return pnode;
  12. }

接着将结点与表头结合:如果是空队列,则使表头的后驱指针与前驱指针都指向结点;如果不是空队列则使表头的后驱结点的指向下一个的指针指向结点,表头的后驱结点也指向结点,最后使队列结点个数加1即可。

  1. int push_queue(QUE_LIST *pque, QUE_NODE *pnode)
  2. {
  3. if (is_empty_queue(pque))
  4. {
  5. pque->prear = pnode;
  6. pque->pfront = pnode;
  7. }
  8. else
  9. {
  10. pque->prear->pnext = pnode;
  11. pque->prear = pnode;
  12. }
  13. pque->clen++;
  14. return 0;
  15. }
出队操作:

用结点结构体定义一个指针,其等于队列表头的头,队列表头的头等于指针的后驱结点,如果队列表头的头为空,则使其尾也为空,如果数据域不为空,则使传入的数据指针的值为数据域的值。最后释放结点,并使结点个数减一。

  1. int pop_queue(QUE_LIST *pque, DATA_TYPE *pdata)
  2. {
  3. if (is_empty_queue(pque))
  4. {
  5. return -1;
  6. }
  7. QUE_NODE *pnode = pque->pfront;
  8. pque->pfront = pnode->pnext;
  9. if (NULL == pque->pfront)
  10. {
  11. pque->prear = NULL;
  12. }
  13. if (pdata != NULL)
  14. {
  15. *pdata = pnode->data;
  16. }
  17. free(pnode);
  18. pque->clen--;
  19. return 0;
  20. }
遍历:

用结点结构体定义一个指针 ,其值等于队列链表的前驱,只要该结点不为空,就打印其数据域的数据,并使该结点的值为该结点的后驱结点。

销毁:

步骤与栈类似:

  1. void destroy_queue(QUE_LIST *pque)
  2. {
  3. while (!is_empty_queue(pque))
  4. {
  5. pop_queue(pque, NULL);
  6. }
  7. free(pque);
  8. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号