数据结构学习——5
一、链表队列
queue.h
/*===============================================
* 文件名称:queue.h
* 创 建 者:青木莲华
* 创建日期:2025年07月31日
* 描 述:链式队列
================================================*/
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int data_t;
typedef struct Node
{
data_t data;
struct Node *next;
}node_t;
typedef struct
{
struct Node *front,*rear;
}queue_t;
//create
queue_t *queue_create();
//empty
int is_empty(queue_t *q);
//length
int queue_length(queue_t *q);
//show
void queue_show(queue_t *q);
//en
int queue_en(queue_t *q,data_t data);
//de
data_t queue_de(queue_t *q);
#endif
queue.c
/*===============================================
* 文件名称:queue.c
* 创 建 者:青木莲华
* 创建日期:2025年07月31日
* 描 述:链式队列
================================================*/
#include "queue.h"
//create
queue_t *queue_create()
{
queue_t *q = (queue_t *)malloc(sizeof(queue_t));
if(q == NULL)
return NULL;
node_t *head = (node_t *)malloc(sizeof(node_t));
if(head == NULL)
{
free(q);
return NULL;
}
head->next = NULL;
q->front = head;
q->rear = head;
return q;
}
//empty
int is_empty(queue_t *q)
{
return q->front->next == NULL;
}
//length
int queue_length(queue_t *q)
{
int count = 0;
node_t *p = q->front->next;
while(p != NULL)
{
count++;
p = p->next;
}
return count;
}
//show
void queue_show(queue_t *q)
{
if(is_empty(q))
{
printf("队已空!\n");
return;
}
node_t *p = q->front->next;
while(p != NULL)
{
printf("%4d ",p->data);
p = p->next;
}
printf("\n");
}
//en
int queue_en(queue_t *q,data_t data)
{
node_t *new = (node_t *)malloc(sizeof(node_t));
if(new == NULL)
return 0;
new->next = NULL;
new->data = data;
q->rear->next = new;
q->rear = new;
return 1;
}
//de
data_t queue_de(queue_t *q)
{
if(is_empty(q))
{
printf("队已空!\n");
return 0;
}
node_t *p = q->front;
q->front = q->front->next;
free(p);
return q->front->data;
}
main.c
/*===============================================
* 文件名称:main.c
* 创 建 者:青木莲华
* 创建日期:2025年07月31日
* 描 述:链式队列
================================================*/
#include "queue.h"
int main(int argc, char *argv[])
{
queue_t *q = queue_create();
if(q == NULL)
return 0;
for(int i = 0 ; i < 10 ; i ++)
queue_en(q,i+1);
queue_show(q);
while(!is_empty(q))
printf("out : %4d\n",queue_de(q));
queue_show(q);
queue_en(q,11);
queue_en(q,22);
queue_en(q,33);
queue_de(q);
queue_show(q);
return 0;
}
运行截图
二、二叉树
1.性质
2.度 概念
3.二叉树的存储
完全二叉树用顺序存储
非完全二叉树用链式存储
4.代码具体实现
结构
typedef char data_t;
typedef struct Node
{
data_t data;
struct Node *lchild;
struct Node *rchild;
}bitree;
(1)初始化
//create 通过键盘输入递归方式初始化树
tree_t *tree_init()
{
data_t ch;
scanf("%c",&ch);
if(ch == '#')
return NULL;
tree_t *root = (tree_t *)malloc(sizeof(tree_t));
if(root == NULL)
return NULL;
root->data = ch;
root->ichild = tree_create();
root->rchild = tree_create();
return root;
}
(2)遍历
//先序遍历
void pre_order(tree_t *root)
{
if(root == NULL)
return;
printf("%c ",root->data)
pre_order(root->lchild);
pre_order(root->rchild);
}
//中序遍历
void mid_order(tree_t *root)
{
if(root == NULL)
return;
mid_order(root->lchild);
printf("%c ",root->data);
mid_order(root->rchild);
}
//后续遍历
void post_order(tree_t *root);
if(root == NULL)
return;
post_order(root->lchild);
post_order(root->rchild);
printf("%c ",root->data);
}
三、作业
1.使用非递归实现层序遍历
队列使用的是 “一、链表队列”
//层序遍历 利用队列实现
void level_order(tree_t *root)
{
if(root == NULL)
return;
queue_t *q = queue_create();
if(q == NULL)
return;
//先将根节点入队
queue_en(q,root);
tree_t *temp = NULL;
//用循环进行入队出队操作 队为空表示所有结点遍历完毕
while(!is_empty(q))
{
temp = queue_de(q); //进行出队操作
if(temp->lchild != NULL) //左子结点不为空 入队
queue_en(q,temp->lchild);
if(temp->rchild != NULL) //右子结点不为空 入队
queue_en(q,temp->rchild);
printf("%c ",temp->data); //打印当前结点的值
}
printf("\n");
}
运行结果
2.使用非递归实现先序遍历
//非递归 先序遍历
void pre_non_R(tree_t *root)
{
if(root == NULL)
return;
stack_t *s = stack_create();
if(s == NULL)
return;
tree_t *temp = NULL; //定义接收出栈结点的指针变量
stack_push(s,root); //根节点入栈
while(!stack_empty(s)) //终止条件 栈为空
{
temp = stack_pop(s); //出栈
printf("%c ",temp->data); //打印
if(temp->rchild != NULL)
stack_push(s,temp->rchild); //根左右 右子结点应该先压栈 先找左结点
if(temp->lchild != NULL)
stack_push(s,temp->lchild); //左子结点入栈,下一次循环再出栈
}
printf("\n");
free(s); //释放空间
}
运行截图
3.非递归 中序遍历
//非递归 中序遍历
void mid_non_R(tree_t *root)
{
if(root == NULL)
return;
stack_t *s = stack_create();
if(s == NULL)
return;
tree_t *temp = root; //当前操作的结点,用于将所有左子结点入栈操作
while(temp != NULL || !stack_empty(s)) //终止条件 栈为空
{
while(temp != NULL) //temp会一直往左找 找到最左侧的结点,为空时再出栈往右
{
stack_push(s,temp); //入栈
temp = temp->lchild; //temp继续往左子结点走
}
temp = stack_pop(s); //当左字节点为空则出栈,并打印,然后往右找
printf("%c ",temp->data);
temp = temp->rchild; //左子结点找完往右找, 继续重复所有左子结点压栈
}
free(s); //释放空间
printf("\n");
}
运行结果