栈、队列和二叉树

栈:先进后出。

进制转换原理图:

 

 

下面是栈的代码

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("\n");
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("\n");
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 ='\0';
  scanf("%c",&ch);
  printf("***************%c\n",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\n",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("\n");
  mid_tree(root);
  printf("\n");
  tail_tree(root);
  printf("\n");
  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 = '\0';
  scanf("%c",&ch);
  printf("*************%c\n",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:有哪里写的不对的,请指正,互相学习。

 

posted @ 2020-03-06 00:57  七章啊  阅读(787)  评论(0编辑  收藏  举报