栈,队列,二叉树是基本的数据结构,我们用C语言来实现它们,并且实现一些基本的方法,包括入栈出栈,二叉树的遍历等等。
#include "stdlib.h"
#include "stdio.h"
typedef struct Node{
int data;
struct Node *next;
}Node;
Node* initStack(){
Node* l = (Node*)malloc(sizeof(Node));
l->next = NULL;
l->data = 0;
return l;
}
void Push(Node* stack,int d){
Node *node = (Node*)malloc(sizeof(Node));
node->data = d;
node->next = stack->next;
stack->next = node;
stack->data++;
}
int Pop(Node* stack){
int res = stack->next->data;
Node *t = stack->next;
stack->next = stack->next->next;
free(t);
return res;
}
首先是栈,我们用链式结构来实现栈,同时实现了入栈和出栈。
#include "stdio.h"
#include "stdlib.h"
typedef struct Node{
int data;
struct Node *next;
}Node;
Node* initQueue(){
Node *q = (Node*)malloc(sizeof(Node));
q->data = 0;
q->next = NULL;
return q;
}
void enQueue(Node *q,int d){
Node *node = (Node*)malloc(sizeof(Node));
node->data = d;
node->next = q->next;
q->next = node;
q->data ++;
}
void deQueue(Node *q){
Node *node = q->next;
while (node->next->next){
node = node->next;
}
free(node->next);
node->next = NULL;
q->data--;
}
然后是队列,队列的特点是先进先出,我们也用链式结构来实现。
#include "stdio.h"
#include "stdlib.h"
typedef struct TreeNode{
int data;
struct TreeNode *lchild;
struct TreeNode *rchild;
}TN;
void createTreeNode(TN** tree){
// 按照前序遍历的顺序创建二叉树
int d;
scanf("%d",&d);
if (d == -1){
*tree = NULL;
}
else {
(*tree) = (TN*)malloc(sizeof(TN));
(*tree)->data = d;
createTreeNode(&((*tree)->lchild));
createTreeNode(&((*tree)->rchild));
}
}
void preOrder(TN* tree){
// 前序遍历
if (tree == NULL){
return;
}
else {
printf("%d ",tree->data);
preOrder(tree->lchild);
preOrder(tree->rchild);
}
}
void inOrder(TN* tree){
// 中序遍历
if (tree==NULL){
return;
}
else {
inOrder(tree->lchild);
printf("%d ",tree->data);
inOrder(tree->rchild);
}
}
void postOrder(TN* tree){
// 后序遍历
if (tree==NULL){
return;
}
else {
postOrder(tree->lchild);
postOrder(tree->rchild);
printf("%d ",tree->data);
}
}
typedef struct Node{
struct TreeNode* data;
struct Node* next;
struct Node* pre;
}QueueNode;
QueueNode* createQueue(){
QueueNode* q = (QueueNode*)malloc(sizeof(QueueNode));
q->next = q;
q->pre = q;
q->data = NULL;
return q;
}
void enQueue(QueueNode* q,TN* node){
if (node==NULL){
return;
}
QueueNode* n = (QueueNode*)malloc(sizeof(QueueNode));
n->data = node;
n->pre = q;
n->next = q->next;
q->next->pre = n;
q->next = n;
}
QueueNode* deQueue(QueueNode* q){
if (q->next == q){
return NULL;
}
QueueNode* node = q->pre;
q->pre = node->pre;
node->pre->next = q;
return node;
}
int isEmpty(QueueNode* q){
if (q->next == q){
return 1;
}
return 0;
}
void levelOrder(TN* tree){
// 层次遍历,使用了一个循环双链表充当队列
QueueNode* q = createQueue();
enQueue(q,tree);
while (!isEmpty(q)){
QueueNode* node = deQueue(q);
printf("%d ",node->data->data);
enQueue(q,node->data->lchild);
enQueue(q,node->data->rchild);
}
}
然后是二叉树,其中重点是:二叉树的前序、中序、后序遍历和层次遍历。层次遍历时,我们使用一个队列来存储遍历的节点,然后每次出队的时候将节点的左子树和右子树入队,通过这种算法来实现二叉树的层次遍历。
二叉树在定义和操作中都有递归的方法,在遍历的时候我们也可以使用递归来实现。
此外、由于递归是可以用栈来实现的,所以我们也可以利用一个栈来实现“非递归”的遍历。
void preOrderNonRecrusion(TN* tree){
Stack* s = createStack();
TN* node = tree;
while (node||!stackIsEmpty(s)){
if (node){
printf("%d ",node->data);
Push(s,node);
node = node->lchild;
}
else {
node = Pop(s)->data;
node = node->rchild;
}
}
}
void inOrderNonRecrusion(TN* tree){
Stack* s = createStack();
TN* node = tree;
while (node||!stackIsEmpty(s)){
if (node){
Push(s,node);
node = node->lchild;
}
else {
node = Pop(s)->data;
printf("%d ",node->data);
node = node->rchild;
}
}
}