目录
二叉树遍历,在结点的左、下、右(前、中、后)画圈并从根节点开始连线,穿过结点圈的即被遍历。
队列的链表实现
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkNode {
ElemType data;
struct LinkNode *next;
} LinkNode;
typedef struct {
LinkNode *front, *rear;//链表头 链表尾,也称为队头队尾
} LinkQueue;//先进先出
//队列的初始化,使用的是带头结点的链表实现
void InitQueue(LinkQueue &Q) {
Q.front = Q.rear = (LinkNode *) malloc(sizeof(LinkNode));
Q.front->next = NULL;
}
//入队
void EnQueue(LinkQueue &Q, ElemType x) {
LinkNode *p = (LinkNode *) malloc(sizeof(LinkNode));
p->data = x;
p->next = NULL;//队尾结点指向NULL
Q.rear->next = p;//从尾部入队,尾指针的next指向当前节点p
Q.rear = p;//rear指向新的尾部
}
//出队
bool DeQueue(LinkQueue &Q, ElemType &x) {
if (Q.rear == Q.front)return false;
LinkNode *q = Q.front->next;//拿到第一个结点,存入q
x=q->data;//获取出队的元素值
Q.front->next = q->next;//让第一个结点断链
if (Q.rear == q) Q.rear = Q.front;//链表最后一个结点被删除时,要改变rea
free(q);
return true;
}
int main() {
LinkQueue Q;
InitQueue(Q);//初始化队列
EnQueue(Q, 3);
// EnQueue(Q, 4);
// EnQueue(Q, 5);
// EnQueue(Q, 6);
// EnQueue(Q, 7);
ElemType elem;
bool ret;
ret = DeQueue(Q, elem);
if (ret)printf("DeQueue success element=%d\n", elem);
else printf("DeQueue failed\n");
ret = DeQueue(Q, elem);
if (ret)printf("DeQueue success element=%d\n", elem);
else printf("DeQueue failed\n");
return 0;
}
队列真题2019-42
代码实现
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next;//指向下一个结点
} LNode, *LinkList;
void EnQueue(LinkList front, LinkList &rear, ElemType val) {
LinkList p;
if (rear->next == front) {
//队列满,申请一个结点的空间,放入队列
p = (LinkList) malloc(sizeof(LNode));
rear->data = val;//入队元素放入rear指向的结点
rear->next = p;
p->next = front;
rear = p;
} else {
//队列不满,直接存放,让rear后移一个结点
rear->data = val;
rear = rear->next;
}
}
void DeQueue(LinkList &front, LinkList rear) {
if (front == rear)printf("Queue is empty\n");
else {
printf("DeQueue is %d\n", front->data);
front = front->next;
}
}
//循环队列操作总流程
void CircleQueue(LinkList &front, LinkList &rear) {
//队首手和对位都指向一个结点,这是的队列既是满队,也是空队
front = (LinkList) malloc(sizeof(LNode));
rear = front;
rear->next = front;//构造循环队列
//入队
EnQueue(front, rear, 3);
EnQueue(front, rear, 4);
//出队
DeQueue(front, rear);
DeQueue(front, rear);
DeQueue(front, rear);
}
int main() {
LinkList front, rear;
CircleQueue(front, rear);
return 0;
}
OJ入栈出栈、入队出队
新建一个栈,读取标准输入3个整数3 4 5,入栈3 4 5,依次出栈,打印 5 4 3,新建循环队列(Maxsize为5),读取标准输入3 4 5 6 7,入队7时,队满,打印false,然后依次出队,输出 3 4 5 6
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 5
typedef int ElemType;
typedef struct {
ElemType data[MaxSize];//数组
int top;//始终指向栈顶位置的变量
} SqStack;
typedef struct {
ElemType data[MaxSize];
int front, rear;
} SqQueue;
void InitStack(SqStack &S) {
S.top = -1;
}
void InitQueue(SqQueue Q) {
Q.front = Q.rear;
}
bool PushStack(SqStack &S, ElemType elem) {
if (MaxSize - 1 == S.top) return false;
S.data[++S.top] = elem;
return true;
}
bool PushQueue(SqQueue &Q, ElemType x) {
if ((Q.rear + 1) % MaxSize == Q.front)return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;
return true;
}
bool PopStack(SqStack &S, ElemType &m) {
if (MaxSize - 1 == S.top)return false;
m = S.data[S.top--];
return true;
}
bool PopQueue(SqQueue &Q, ElemType &m) {
if(Q.rear==Q.front) return false;
m=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
int main() {
ElemType elem;
SqStack S;
InitStack(S);
for (int i = 0; i < 3; i++) {
scanf("%d", &elem);
PushStack(S, elem);
}
for (int i = 0; i < 3; ++i) {
PopStack(S, elem);
printf("%2d", elem);
}
printf("\n");
SqQueue Q;
InitQueue(Q);
bool flag;
for (int i = 0; i < 5; i++) {
scanf("%d", &elem);
flag = PushQueue(Q, elem);
if (!flag)printf("false\n");
}
for (int i = 0; i < 4; i++) {
PopQueue(Q, elem);
printf("%2d", elem);
}
return 0;
}
树
二叉树
代码实现:
#include <stdio.h>
#include <stdlib.h>
typedef char BiElemType;
typedef struct BiTNode {
BiElemType c;
struct BiTNode *lchild;
struct BiTNode *rchild;
} BiTNode, *BiTree;
//tag结构体时辅助队列使用的
typedef struct tag {
BiTree p;//树的某结点的地址值
struct tag *pnext;
} tag, *ptag;
int main() {
BiTree pnew;//用来指向新申请的树结点
BiTree tree = NULL;//tree是指向树根的,代表树
ptag phead = NULL, ptail = NULL, listpnew = NULL, pcur;
char c;
//abcdefghij
while (scanf("%c", &c)) {
if (c == '\n')break;
//calloc申请的空间大小是两个参数直接相乘,并对空间进行初始化,赋值为0
pnew = (BiTree) calloc(1, sizeof(BiTNode));
pnew->c = c;
listpnew = (ptag) calloc(1, sizeof(tag));//给队列结点申请空间
listpnew->p = pnew;
//如果是树的第一个结点
if (NULL == tree) {
tree = pnew;//tree指向树的根结点
phead = listpnew;//第一个结点即队列头,也是队列尾
ptail = listpnew;
pcur = listpnew;//pcur要指向要进入树的父节点
} else {
//让元素进入队列
ptail->pnext = listpnew;
ptail = listpnew;
//接下来把左孩子或右孩子结点放入树中
if (NULL == pcur->p->lchild) { pcur->p->lchild = pnew; }//右孩子为空,放到右孩子中
else if (NULL == pcur->p->rchild) {
pcur->p->rchild = pnew;//左孩子为空,放到左孩子中
pcur = pcur->pnext;
}
}
}
return 0;
}
二叉树遍历
前序遍历:先打印当前结点,再打印左子树,再打印右子树。也称深度优先遍历。
中序遍历:先打印左子树,再打印当前结点,再打印右子树。(二维变成一维的结果)
后序遍历:先打印左子树,再打印右子树,再打印当前结点。
每次看一个子树,本质是递归,从根节点开始,往前写。遍历结果是逻辑顺序。
层序遍历:自上而下,从左自右打印。也称广度优先遍历。
这里分享B站快速找出前中后序遍历的方法:在结点的左、下、右(前、中、后)画圈并从根节点开始连线,穿过结点圈的即被遍历。【纯干货】三分钟教会你遍历二叉树!学不会举报我!!_哔哩哔哩_bilibili无脑秒解!已知先/后序遍历与中序遍历,求后/先序遍历。_哔哩哔哩_bilibili
//前序遍历,即先序遍历,即深度优先遍历
void PreOrder(BiTree p) {
if (NULL != p) {
printf("%c", p->c);
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
//中序遍历
void MidOrder(BiTree p) {
if (NULL != p) {
MidOrder(p->lchild);
printf("%c", p->c);
MidOrder(p->rchild);
}
}
//后序遍历
void PostOrder(BiTree p) {
if (NULL != p) {
PostOrder(p->lchild);
PostOrder(p->rchild);
printf("%c", p->c);
}
}
//层序遍历
void LevelOrder(BiTree T) {
LinkQueue Q;
InitQueue(Q);
BiTree p;//存储出队的结点
EnQueue(Q, T);//把根结点入队
while (!IsEmpty(Q)) {
DeQueue(Q, p);
putchar(p->c);
if (p->lchild) EnQueue(Q, p->lchild);//左孩子不为空,就入队左孩子
if (p->rchild) EnQueue(Q, p->rchild);//右孩子不为空,就入队右孩子
}
}