队列,树 day23

六:队列(一般做缓冲区,缓冲队列)

一:定义

队列是只允许在一段进行插入,而在另一端进行删除操作的线性表。允许插入的称谓队尾,允许删除的一端叫队头。

​ 顺序队列。循环队列

​ 常用操作,入队,出队。

​ 先进先出,FIFO

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

typedef int DATATYPE;
typedef struct queue {
	DATATYPE *array;
	int tlen;
	int head;
	int tail;
}SeqQueue;
二:CreateSeqQueue
SeqQueue *CreateSeqQueue(int len)
{
    SeqQueue* sq = malloc(sizeof(SeqQueue));
    if(NULL == sq)
    {
        fprintf(stderr,"CreateSeqQueue malloc error\n");
        return NULL;

    }
    sq->array = malloc(sizeof(DATATYPE)*len);
    if(NULL == sq->array)
    {
        fprintf(stderr,"CreateSeqQueue malloc2 error\n");
        return NULL;

    }
    sq->head = 0 ;
    sq->tail = 0;
    sq->tlen = len;
    return sq;

}

三:EnterSeqQueue

int EnterSeqQueue(SeqQueue *queue, DATATYPE *data)
{
    if(IsFullSeqQueue(queue))
    {
        printf("queue is full\n");
        return 1;
    }
    memcpy(&queue->array[queue->tail],data,sizeof(DATATYPE));
    queue->tail = (queue->tail+1)%queue->tlen;
    return 0;
}
四:QuitSeqQueue
int QuitSeqQueue(SeqQueue *queue)
{
    if(IsEmptySeqQueue(queue))
    {
         printf("queue is empty\n");
        return 1;
    }
    queue->head = (queue->head+1)%queue->tlen;
    return 0;
}
五:IsEmptySeqQueue/IsFullSeqQueue
int IsEmptySeqQueue(SeqQueue *queue)
{
    return queue->head == queue->tail;//tail = head
}
int IsFullSeqQueue(SeqQueue *queue)
{
    return (queue->tail +1)%queue->tlen == queue->head;//tail+1 = head
    //代码的作用是更新队头指针head的位置,而取模运算%是为了实现循环队列(CircularQueue)的特性
}
六:GetHeadSeqQue
DATATYPE* GetHeadSeqQue(SeqQueue *queue)
{
    if(IsEmptySeqQueue(queue))
    {
        return NULL;
    }
    return &queue->array[queue->head];
}
七:DestroySeqQueue
int DestroySeqQueue(SeqQueue *queue)
{
    free(queue->array);
    free(queue);
    return 0;
}

七:树

一:定义

树:n(n>=0)个结点的有限集合。n = 0 ,空树。

在任意一个非空树中,
1,有且仅有一个特定的根结点
2,当n>1 时,其余结点可分为m个互不相交的有限集合T1,T2,T3.。。。。Tm,其中每一个集合又是一个树,并且称谓子树。

结点拥有子树的个数称谓结点的度。度为0的结点称谓叶结点。度不为0,称谓分支结点。

树的度数是指,这棵树中,最大的结点的度数,称谓树的度数。

树的深度或高度,从根开始,根为第一层,根的孩子为第二层。

树的存储:顺序结构,链式结构。

二:二叉树

二叉树,binary tree
n个结点的有限集合,集合要么为空树,要么由一个根结点和两棵互不相交,分别称谓根结点的左子树和右子树的二叉树组成。。

特点,
1,每个结点最多两个子树。
2,左子树和右子树是有顺序的,次序不能颠倒。
3,如果某个结点只有一个子树,也要区分左,右子树。


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特殊的二叉树
1,斜树,所有的结点都只有左子树,左斜树,所有结点都只有右子树,右树。
2,满二叉树,所有的分支结点都存在左右子树,并且叶子都在同一层上。
3,完全二叉树,对于一颗有n个结点的二叉树按层序编号,如果编号i(1<=i<=n)的结点于同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这可树为完全二叉树。(从左往右,从上到下边,编号与满二叉树一模一样)


特性
1,在二叉树的第i层上最多有2^(i-1)个结点 i>=1
2,深度为k的二叉树至多有2^k -1 个结点 k>=1
3,任意一个二叉树T,如果其叶子结点的个数是n0,度数为2的结点数为n2, n0 = n2 +1;(度为2的结点个数+1)
4,有n个结点的完全二叉树深度为(logn/log 2) +1;

三:遍历的三种

层序,(用的递归的写法)
前序,根左右,先访问根,然访问左,访问右。
中序,左根右,先从根开始(不是先访问根),从左开始访问,在访问根,在访问右结点。
后序,左右根,先从根开始(不是先访问根),先访问左,在访问右。在访问根。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四:二叉树基本调试

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

typedef char DATATYPE;
typedef struct BiTNode
{
    DATATYPE data;
    struct BiTNode *lchild,*rchild;
}BitTNode;

char dat[] = "abd##eh###c#fi###";
int ind = 0;

void CreateTree(BitTNode ** root)//二重指针,用地址修改main函数
{
    char c = dat[ind++];
    if('#' == c)
    {
        *root = NULL;
    }else
    {
        *root = malloc(sizeof(BitTNode));
        if(NULL == *root)
        {
            printf("malloc errorn\n");
            return;
        }
        (*root)->data = c;
        CreateTree(&(*root)->lchild);
        CreateTree(&(*root)->rchild);
    }
    return;
}

void PreOrderTraverse(BitTNode * root)
{
    if(NULL == root)
    {
        return ;
    }else
    {
        printf("%c",root->data);
        PreOrderTraverse(root->lchild);
        PreOrderTraverse(root->rchild);
    }
}

int	main(int argc, char **argv)
{
    BitTNode * root = NULL;
    CreateTree(&root);
    PreOrderTraverse(root);


    system("pause");
    return 0;
}
一:treegdb调试
gcc -g main.c//生成a.out
gdb ./a.out	//调试gdb
b CreatTree//在此函数设置断点
r			//运行
display c	//一直显示XX函数中 追踪的c的状态
n			//向下一行运行
bt			//显示目前程序已有数据赋值或者XX的具体状态
二:PreOrderTraverse前序
/**
 * @brief  根左右
 * 
 * @param root 
 */
void PreOrderTraverse(BiTNode*root)
{
    if(NULL==root )
    {
        return ;
    }
    else  
    {
        printf("%c",root->data);//root 
        PreOrderTraverse(root->lchild);// lift
        PreOrderTraverse(root->rchild);// right
    }
}
三:InOrderTraverse中序
/**
 * @brief 左根右
 * 
 * @param root 
 */
void InOrderTraverse(BiTNode* root)
{
    if(NULL == root)
    {
        return ;
    }
    InOrderTraverse(root->lchild);
    printf("%c",root->data);
    InOrderTraverse(root->rchild);
}
四:PostOrderTraverse后序
/**
 * @brief 左右根
 * 
 * @param root 
 */
void PostOrderTraverse(BiTNode* root)
{
    if(NULL == root)
    {
        return ;
    }
    PostOrderTraverse(root->lchild);
    PostOrderTraverse(root->rchild);
    printf("%c",root->data);
}
五:DestroyBiTree销毁
void DestroyBiTree(BiTNode*root)
{
    if(NULL ==root)
    {
        return ;
    }
    DestroyBiTree(root->lchild);
    DestroyBiTree(root->rchild);
    free(root);
}
六:逐层遍历二叉树(练习)
.h文件
typedef struct BiTNode* DATATYPE1; // 修改为存储二叉树节点指针
//这是最重要的,直接改为能放入二叉树,通过节点放入
typedef struct queue {
	DATATYPE1 *array;
	int tlen;
	int head;
	int tail;
}SeqQueue;

typedef char DATATYPE2;
typedef struct BiTNode  /* 结点结构 */
{
   DATATYPE2 data;		/* 结点数据 */
   struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
}BiTNode;

SeqQueue *CreateSeqQueue(int len);
int EnterSeqQueue(SeqQueue *queue, DATATYPE1 *data);
int QuitSeqQueue(SeqQueue *queue);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
DATATYPE1* GetHeadSeqQue(SeqQueue *queue);
int DestroySeqQueue(SeqQueue *queue);
void CreateTree(BiTNode **root);
void DestroyBiTree(BiTNode *root);
.c文件,此为修改部分,其他部分不变
int ind = 0;
void CreateTree(BiTNode **root)
{
  char dat[] = "abd##eh###c#fi###";//二叉树元素
  char c = dat[ind++];
  if ('#' == c)
    {
      *root = NULL;
    }
  else
    {
      *root = malloc(sizeof(BiTNode));
      if (NULL == *root)
        {
          printf("malloc error\n");
          return;
        }
      (*root)->data = c;
      CreateTree(&(*root)->lchild);
      CreateTree(&(*root)->rchild);
    }
  return;
}
main函数
int main(int argc, char** argv)
{
  BiTNode* root = NULL;
  CreateTree(&root);
  //char dat[] = "abd##eh###c#fi###";
  SeqQueue* sq = CreateSeqQueue(20);
  EnterSeqQueue(sq, &root);//把第一个根放进去(首根)

  while (!IsEmptySeqQueue(sq))
    {
      BiTNode * tmp = *GetHeadSeqQue(sq);//获得队列的头元素
      QuitSeqQueue(sq);
      printf("%c ", tmp->data);

      if(tmp->lchild != NULL)
      {
        EnterSeqQueue(sq,&tmp->lchild);
      }
    if(tmp->rchild != NULL)
      {
        EnterSeqQueue(sq,&tmp->rchild);
      }
    }
    putchar('\n');

  DestroySeqQueue(sq);
  DestroyBiTree(root);

  // system("pause");
  return 0;
}//先全部放进去,然后拿出来比较二叉树元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值