zoukankan      html  css  js  c++  java
  • 栈、队列和二叉树

    栈:先进后出。

    进制转换原理图:

    下面是栈的代码

    stack.h
    
    #ifndef STACK_H
    #define STACK_H
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    typedef struct StackNode{
        elemType data;
        struct StackNode *next;
    }Stack;

    //创建栈节点/栈--创建单链表节点
    struct StackNode *create_node(elemType data0;
    //压栈
    bool Push_stack(Stack*头皮,elemType data);
    //出栈--单链表头删法
    bool pop_stack(Stack *top,elemType *data);
    #endif
    stack.c

    #include "stack.h"

    //创建栈节点/栈--创建单链表节点
    struct StackNode *create_node(elemType data)
    {
      struct StackNode *node = malloc(sizeof(struct StackNode));
      if(node == NULL){
        perror("mallloc fail:");
        return NULL;
      }
      node->data = data;
      node->next = NULL;
      return node;
    }

    //压栈--单链表头插法
    bopl push_stack(Stack *top,elemType data)
    {
      if(top == NULL){
        perror("栈不存在");
        return false;
      //创建一个节点
      Stack *node = create_node(data);
      node->next = top->next;
      top->next = node;
      retrun true;
    }

    //出栈--单链表头删法
    bool delete_stack(Stack *top,elemType *data)
    {
      if(top == NULL)
      {
        perror("栈不存在");
        return false;
      }
      Stack *node = top->next;

      if(node == NULL)
      {
        perror("栈是空的");
        return false;
      }
      //把node从栈上删除
      top->next =node->next;
      //先把node中的数据存好再删除节点
      *data = node->data;
      free(node);
      node = NULL;
      return true;
    }
     1 1栈.c
     2 
     3 #include <stdio.h>
     4 #include "stack.h"
     5 
     6 int main
     7 {
     8     //创建栈
     9     Stack  *top = create_node(0);
    10     
    11     for(int i = 0;i<10;i++)
    12     {
    13         push_stack(top,i);
    14     }
    15     
    16     //出栈
    17     int data = 0;
    18     while(pop_stack(top,&data))
    19         printf("%d",data);
    20         printf("
    ");
    21 
    22     //栈实现进制转换
    23     int obj = 0;
    24     scanf("%d",&obj);
    25     
    26     while(obj)
    27     {
    28         push_stack(top,obj%2);
    29         obj = obj/2;
    30     }
    31     while(pop_stack(top,&data));
    32     printf("%d",data);
    33     printf("
    ");
    34 
    35     return 0;
    36 }

    队列:先进先出

    下面是队列的代码:

    1队列.c

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

    typedef int elemType;
    struct Node{
      elemType data;
      struct Node *next;
    };

    typedef struct _Queue
    {
      int length;
      struct Node *start;
      struct Node *end;
    }Queue;

    //创建队列
    Queue *create_queue(0
    {
      Queue *q = malloc(sizeof(Queue));
      //创建一个队列
      q->length = 0;
      q->start = q->end = NULL;
      return q;
    }

    //入队列--链表尾插法
    bool enter_queue(Queue *q,elemType data)
    {
      if(q == NULL)
      {
        perror("队列错误");  
        return false;
      }
      if(q->length == 0)//队列为空
      {
        struct Node *node = malloc(sizeof(struct Node));
        node->data = data;
        node->next = NULL;
        q->start = q->end = NULL;
        q->length = 1;
      }else{
        struct Node *node = malloc(sizeof(struct Node));
        node->data = data;
        node->next = NULL;
        //node放在end后面
        q->end->next = node;  
        //把end指向链表尾部
        q->end = node;
        q->length++;
      }
      return true;
    }

    //出队列--链表头删法
    bool out_queue(Queue *q,elemType data)
    {
      if(q == NULL)
      {
        perror("队列错误");
        return false;
      }
      if(q->length == 0)
      {
        return false;
      }

      //从start开始删除数据
      if(q->start == q->end)
      {
        *data = q->start->data;
        free(q->start);
        q->start = q->end = NULL;
        q->length = 0;
      }else{
        *data = q->start->data;
        //暂存start
        struct Node *tmp = q->start;
        //start往后移动
        q->start = q->start->next;
        q->length--;
      }
      return true;
    }

    int get_queue_length(Queue *q)
    {
      if(q == NULL)
      {
        perror('队列错误");
        return -1;
      }
      return q->length;
    }

    int main
    {
      Queue *q = create_queue();
      for(int i= 0;i<10;i++)
      {
        enter_queue(q,i);
      }

      int data = 0;
      while(out_queue(q,&data)
        printf("%d",data);
      return 0;
    }

     二叉树

    树的基本概念:树只有一个根节点,多个叶节点。树的层数,树的深度,树的叶子。

    二叉树:一个根节点,每个节点最多两个直接后继。

    二叉树的特性:

     完全二叉树:

     满二叉树:

     设计二叉树

    struct BTree
    {
        int data;
        struct BTree *lchild;
        struct BTree *rchild;
    }

    二叉树的遍历:

    前序遍历:先根节点,在左叶子,最后右叶子。(前序遍历第一个就是根节点)

    中序遍历:先左节点,再根节点,最后右节点。(中序遍历根节点左边是左边的树,右边是右边的树)

    后序遍历:先左节点,再右节点,最后根节点。(后序遍历最后一个是根节点)

    前序遍历:ABDEFGCH

    中序遍历:DBFEGAHC

    后序遍历:DFGEBHCA

    前序遍历:ABCEDFGH

    中序遍历:BECAGFHD

    写出后序遍历

     二叉树递归遍历的实现

    原理图

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

    typedef struct BTree
    {
      char data;
      struct BTree *lchild;
      struct BTree *rchild;
    }BiTree;

    //前序创建树
    BiTree *create_tree()
    {
      char ch ='';
      scanf("%c",&ch);
      printf("***************%c ",ch);
      
      if(ch == '#')
      {
        return NULL;
      }else{
        BiTree *root = malloc(sizeof(BiTree));
        root->data = ch;
        root->lchild = create_tree();
        root->rchild = create_tree();
        return root;
      }
    }

    //三种遍历都是不停地递归,直到这边遍历完了,再递归遍历另一边
    //前序遍历
    void show_tree(BiTree *root)
    {
      if(root == NULL)return;
      printf("c ",root->data);
      show_tree(root->lchild);
      show_tree(root->rchild);
    }

    //中序遍历
    void_mid_tree(BiTree *root)
    {
      if(root == NULL)return;
      mid_tree(root->lchild);
      printf("%c",root->data);
      mid_tree(root->rchild);
    }

    //后序遍历
    void tail_tree(BiTree *root)
    {
      if(root == NULL)return;
      tail_tree(root->lchild);
      tail_tree(root->lchild);
      printf("%c",root->data);
    }

    //销毁二叉树
    void destroy_tree(BiTree *root)
    {
      //后序遍历销毁
      if(root == NULL)return;
      destroy_tree(root->lchild);
      destroy_tree(root->rchild);
      free(root);
      root = NULL;
    }

    int main()
    {
      BiTree *root = create_tree();
      show_tree(root);
      printf(" ");
      mid_tree(root);
      printf(" ");
      tail_tree(root);
      printf(" ");
      return 0;
    }

     下面是二叉树的非递归遍历的实现

    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdlib.h>

    typedef struct BTree
    {
      char data;
      struct BTree *lchild;
      struct BTree *rchild;
    }BiTree;

    //创建一个栈--链表
    typedef struct Stack
    {
      struct Btree *node;
      struct BTree *next;
    }Stack;

    //创建一个栈
    Stack *create_node(BiTree *node)
    {
      Stack *mstack = malloc(sizeof(Stack));
      mstack->node = node;
      mstack->next = NULL;
      return mstack;
    }

    //压栈
    bool push_stack(Stack *top,BiTree *node)
    {
      if(top == NULL)return false;
      Stack *snode = create_node(node0;
      snode->next = top->next;
      top->next = snode;
      return true;
    }

    //出栈
    BiTree *pop_stack(Stack *top)
    {
      if(top == NULL || top->next == NULL)return NULL;
      Stack *snode = top->next;
      top->next = snode->next;
      BiTree *tree = snode->data;
      free(snode);
      return tree;
    }

    //前序创建树
    BiTree *create_tree()
    {
      char ch = '';
      scanf("%c",&ch);
      printf("*************%c ",ch);
      
      if(ch == '#')
      {
        return NULL;
      }else{
        BiTree *root = malloc(sizeof(BiTree));
        root->data = ch;
        root->lchild = create_tree();
        root->rchild = create_tree();
        return root;
      }
    }

    int main()
    {
      //创建树
      BiTree *tree = create_tree();
      //创建栈
      Stack *top = create_node(NULL);
      //前序遍历
      push_stack(top,tree);
      BiTree oTree = NULL;
      while(oTree = pop_stack(top))
      {
        printf("%c",oTree->data);
        //压右子树
        if(oTree->rchild != NULL)
        {
          push_stack(top,oTree->rchild);
        }
        if(oTree->lchild != NULL)
        {
          push_stack(top,oTree->lchild);
      }
    }

    PS:有哪里写的不对的,请指正,互相学习。

  • 相关阅读:
    JavaSE学习(二):进制转换—数据类型转换—Java运算符
    JavaSE学习(五):数组及其基础操作
    iOS工作中的经验总结—马甲包审核以及常见审核问题!!!(干货)
    月薪过万不是梦!2018年最全/最新Python面试题(整理汇总)
    Python:爬虫技巧总结!
    【转】maven学习(下) 利用Profile构建不同环境的部署包
    【转】maven学习(上) 基本入门用法
    Java从控制台获取数据的方法
    【转】LinkedHashMap实现由插入集合的顺序输出
    浅谈String/StringBuffer/StringBuilder字符串的拼接
  • 原文地址:https://www.cnblogs.com/smallqizhang/p/12423803.html
Copyright © 2011-2022 走看看