数据结构(树、队列、栈)

树结构

结点的度(Degree):结点拥有的子树数目
树的度:树中各结点度的最大值
叶子结点(Leaf):度为0的结点
孩子结点(Child):一个结点的子树的根结点
双亲结点(Parent):与孩子结点对应
兄弟结点(Sibling):一个双亲结点的孩子结点之间为兄弟结点
结点的层次(Level):从根结点开始,根结点为第一层,根结点的孩子结点为第二层,以此类推。
树的深度(Depth):树中结点的最大深度

树的性质
在这里插入图片描述

二叉树

满二叉树:一颗二叉树的任意一个结点或者是叶子结点,或者有两颗子树,同时叶子结点都集中在二叉树的最下面一层
完全二叉树:二叉树中最多只有最下面两层结点的度小于2,且最下面一层的结点都依次排列在该层最左边的位置上

例如:
在这里插入图片描述
二叉树的性质

在这里插入图片描述
二叉树的创建与遍历

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

struct treenode
{
	int data;
	treenode * left;
	treenode * right;
};

typedef treenode Node;

Node *create(int a[],int length)
{
	int i;
	Node *p[length] = {0};   //指针数组
	for(i = 0; i < length; i ++)  //写入数据
	{
		p[i] = (Node *)malloc(sizeof(Node));
		if(p[i] == NULL)
		{
			return NULL;
		}
		p[i]->data = a[i];
		p[i]->left = NULL;
		p[i]->right = NULL;
	}
	for(i = 0;i < length/2 ; i ++)  //连接结点
	{
		p[i]->left = p[2 * i + 1];
		p[i]->right = p[2 *i + 2];
	}
	return p[0];
}

void prenode(Node *root)  //前序 (根——左——右)
{
	if(root == NULL)
	{
		return;
	}
	printf("%d ",root->data);
	prenode(root->left);
	prenode(root->right);
}

void Midnode(Node *root) //中序 (左——根——右)
{
	if(root == NULL)
	{
		return;
	}
	midnode(root->left);
	printf("%d ",root->data);
	midnode(root->right);
}

void posnode(Node * root)//后序 (左——右——根)
{
	if(root == NULL)
	{
		return;
	}
	postnode(root->left);
	postnode(root->right);
	printf("%d ",root->data);
}

int main()
{
	int a[] = {0,1,2,3,4,5,6,7,8,9};
	int length = sizeof(a)/sizeof(int);

	Node *root = create(a,length);
	prenode(root);
	printf("\n");
	midnode(root);
	printf("\n");
	posnode(root);
	printf("\n");

return 0;
}

二叉树的遍历
先序列创建一颗二叉树

void CreateBiTree(BiTree *T)
{
	char c;
	scanf("%c",&c);
	if(c ==' ')
	{
		*T = NULL;
	}
	else
	{
		*T = (BiTNode *)malloc(sizeof(BiTNode));  //创建根结点
		(*T)->data = c;                                          //放入数据
		CreateBiTree(&((*T)->lchild));                //递归的创建左子树
		CreateBiTree(&((*T)->lchild));                //递归的创建右子树
	}
}

先序遍历(根结点→左子树→右子树)

void PreOrderTraverse(BiTree T)
{
	if(T)
	{
		printf("%d\n",T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}

中序遍历(左子树→根结点→右子树)

void InOrderTraverse(BiTree T)
{
	if(T)
	{
		InOrderTraverse(T->lchild);
		printf("%d",T->data);
		InOrderTraverse(T->rchild);
	}
}

后序遍历(左子树→右子树→根结点)
层序遍历(对二叉树中的结点层数从上往下,同一层结点从左向右的顺序进行)

void layerOrderTraverse(BiTree T)
{
	BiTree p;
	queue<BiTree>q;
	if(T != NULL)
	{
		q.push(T);             //将根结点的指针入队列
		while(!q.empty())
		{
			p = q.front();    //取出队头元素
			q.pop();           //从队列中删除队头元素
			visit(p);            //访问p指向的结点元素
			if(p ->lchild != NULL)
			{
				q.push(p->lchild);     //将p结点的左孩子结点指针入队列
			}
			if(p->rchild != NULL)
			{
				q.push(p->rchild);
			}
		}
	}
}

哈夫曼树和哈夫曼编码

二叉排序树

二叉排序树的性质:
1、若它的左子树不为空,则左子树上的所有结点的值均小于根结点的值
2、若它的右子树不为空,则右子树上的所有结点的值均大于根结点的值
3、二叉排序树的左右子树也是二叉排序树
如图
在这里插入图片描述
给定一个关键字key,在二叉排序树T中查找该关键字

BiTree SearchBST(BiTree T,dataType key)
{
	if(T == NULL)
	{
		return NULL;
	}
	if(T->data == key)
	{
		retrun T;
	}
	if(key < T->data)
	{
		return SearchBST(T->lchild,key);
	}
	else
	{
		retrun SearchBST(T->rchild,key);
	}
}

栈(Stack)

先进后出
栈顶(Top):栈的表尾,即插入和删除数据的地方(表头称为栈底)
栈的初始化

typedef struct
{
	ElemType *base;
	ElemType *top;
	int stacksize;          //长度
}sqStack;

int initStack(sqStack *s)
{
	s->base = (ElemType *)malloc(10*sizeof(ElemType));
	if(! s->base)
	{
		return 0;
	}
	s->top =s->base;
	s->stacksize = 10;
	return 1;
}

入栈

int Push(sqStack *p,ElemType e)
{
	if(s->top  -  s->base >= s->stacksize)  //栈满追加空间
	{
		s->base = (ElemType *)realloc(s->base,(s->stacksize  +  10) * sizeof(ElemType));
		if(!s->base)
		{
			return 0;
		}
		s->top = s->base + s->stacksize;
		s->stacksize = s->stacksize  + 10;
	}
	*(s->top) = e;
	s->top ++;
	return 1;
}

出栈

int Pop(sqStack *s,ElemType *e)
{
	if(s->top == s->base)
	{
		return 0;
	}
	*e = * --(s-top);
	return 1;
}

队列(Queue)

先进先出
队尾插入数据,队头取出数据

初始化队列

#define SIZE 100

struct Queue
{
      int data[SIZE];    //存放数据
      int front;       //队头指针
      int rear;        //队尾指针
};
typedef struct Queue queue;

 void InitQueue(queue **q)
  {
       if (NULL == q)
       {
           return ;
       }
 
      *q = (queue *)malloc(sizeof(queue));
      if (NULL == *q)
      {
          return ;
      }
  
      (*q)->rear = (*q)->front = 0;
 }

进队

int EnterQueue(queue *q, int e)
 {
           if(NULL == q)
 	 {
            	return FAILURE;
      	 }
 
         if((q->rear + 1) % SIZE == q->front)   //判断是否队满
         {
                return FAILURE;
         }
 
         q->data[q->rear] = e;
         q->rear = (q->rear + 1) % SIZE;       //防止rear越界
  
   return SUCCESS;
 }

出队(只能删除,不能遍历)

int DelQueue(queue *q)
 {
      if (NULL == q)
      {
          return FAILURE;
      }
  
      if (q->rear == q->front)   //空队
      {
          return FAILURE;
      }
  
      int e = q->data[q->front];   //记录队头元素
      q->front = (q->front + 1) % SIZE;
  
      return e;
  }

销毁队列

int DestroyQueue(queue **q)
 {
      if (NULL == q)
      {
          return FAILURE;
      }
 
      free(*q); 
      *q = NULL;
 
  return SUCCESS;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值