二叉树先序遍历的实现思想是:
- 访问根节点
- 访问当前节点的左子树
- 若当前节点无左子树,则访问当前节点的右子树
以上图 为例,采用先序遍历的思想遍历该二叉树的过程为:
- 访问该二叉树的根节点,找到 节点1
- 访问节点 1 的左子树,找到节点 2
- 访问节点 2 的左子树,找到节点 4
- 由于访问节点 4 左子树失败,且也没有右子树,因此以节点 4 为根节点的子树遍历完成,但节点 2 还没有遍历其右子树,因此现在开始遍历,即访问节点 5
- 由于节点 5 无左右子树,因此节点 5 遍历完成,并且由此以节点 2 为根节点的子树也遍历完成,现在回到节点 1 ,并开始遍历该节点的右子树,即访问节点 3
- 访问节点 3 左子树,找到节点 6
- 由于节点 6 无左右子树,因此节点 6 遍历完成,回到节点 3 并遍历其右子树,找到节点 7
- 节点 7 无左右子树,因此以节点 3 为根节点的子树遍历完成,同时回归节点 1,由于节点 1 的左右子树全部遍历完成,因此整个二叉树遍历完成
因此,上图中二叉树采用先序遍历得到的序列为:1 2 4 5 3 6 7
2 算法设计算法1:
- 根结点入栈并访问根结点
- 栈顶结点设为当前结点,找到结点的左孩子,左孩子为空则进入操作4,左孩子不为空则访问左孩子并将其入栈,同时将结点左孩子置空,代表已访问结点左孩子
- 重复操作2
- 栈顶结点设为当前结点,找到结点的右孩子,右孩子不为空则进入操作6,右孩子为空则代表子树遍历结束,弹出栈顶结点,栈空则遍历结束
- 重复操作4
- 访问右孩子并将其入栈
- 重复操作2
算法2:
3 C语言实现算法1
- 根结点入栈
- 弹出栈顶结点并将其设为当前结点,栈空则遍历结束
- 访问结点并找到结点的右孩子,右孩子不为空则将右孩子入栈,左孩子设为当前结点
- 结点不为空进入操作3,结点为空进入操作2
代码:
'''C #include#include #include #define STACK_INITSIZE 100 #define STACK_INCREMENT 10 //****************************************************************** // 创建树 //****************************************************************** //树结点结构体 typedef struct node { int data; struct node *lchild, *rchild; }BiNode, *BiTree; //创建一个简单的树,返回树的根结点指针 BiTree createBiTree() { BiTree T=(BiNode *)malloc(sizeof(BiNode)); T->data=1; T->lchild=(BiNode *)malloc(sizeof(BiNode)); T->rchild=(BiNode *)malloc(sizeof(BiNode)); T->lchild->data=2; T->lchild->lchild=(BiNode *)malloc(sizeof(BiNode)); T->lchild->rchild=(BiNode *)malloc(sizeof(BiNode)); T->lchild->rchild->data=5; T->lchild->rchild->lchild=NULL; T->lchild->rchild->rchild=NULL; T->rchild->data=3; T->rchild->lchild=(BiNode *)malloc(sizeof(BiNode)); T->rchild->lchild->data=6; T->rchild->lchild->lchild=NULL; T->rchild->lchild->rchild=NULL; T->rchild->rchild=(BiNode *)malloc(sizeof(BiNode)); T->rchild->rchild->data=7; T->rchild->rchild->lchild=NULL; T->rchild->rchild->rchild=NULL; T->lchild->lchild->data=4; T->lchild->lchild->lchild=NULL; T->lchild->lchild->rchild=NULL; return T; } //**************************************************************** // 创建栈 //**************************************************************** //栈结构体 typedef struct { BiNode *base; BiNode *top; int size; }BiStack; //栈初始化 BiStack stackInit() { BiStack s; s.base = (BiNode *)malloc(sizeof(BiNode)*STACK_INITSIZE); s.top = s.base; s.size =STACK_INITSIZE; return s; } //入栈 void push(BiStack *s, BiNode e) { if(s->top - s->base >= s->size) { s->size += STACK_INCREMENT; s->base = (BiNode *)realloc(s->base, sizeof(BiNode)*s->size); } *s->top = e; s->top++; } //出栈 BiNode pop(BiStack *s) { BiNode temp; s->top--; temp = *s->top; return temp; } //得到栈顶元素,但不出栈 BiNode getTop(BiStack s) { BiNode temp; s.top--; temp = *s.top; return temp; } //********************************************************************* // 使用栈结构先序遍历二叉树 //********************************************************************* int time = 0; //记录访问结点次数 //访问结点 void visitNode(BiNode *root) { time++; printf("第%d次访问的结点是:%dn", time, root->data); } int cnt = 0; //记录栈变化次数 int stack[20][20]; //记录栈每次改变时栈中结点的数据 //遍历栈中结点 void traverseStack(BiStack s) { int i = 0; while(s.base != s.top) { stack[cnt][i] = s.base->data; i++; s.base++; } stack[cnt][i] = 0xFFFFFFFF; cnt++; } //先序遍历二叉树 void preTraverse(BiTree T) { BiStack bs = stackInit(); traverseStack(bs); BiNode root = *T; BiNode *temp = NULL; push(&bs, root); //根结点入栈 traverseStack(bs); visitNode(&root); while(bs.top != bs.base) //栈空表示遍历结束 { root = getTop(bs); temp = root.lchild; //先访问左孩子 while(temp != NULL) //左孩子不为空 { //将结点左孩子设为空,代表已访问其左孩子 root.lchild = NULL; pop(&bs); push(&bs, root); //左孩子入栈 root = *temp; temp = root.lchild; push(&bs, root); traverseStack(bs); visitNode(&root); } temp = root.rchild; //后访问右孩子 while(temp == NULL) //右孩子为空,代表左右孩子均已访问,结点可以出栈 { //结点出栈 pop(&bs); traverseStack(bs); if(bs.top == bs.base) break; //根结点出栈,遍历结束 //查看上一级结点是否访问完左右孩子 root = getTop(bs); temp = root.rchild; } if(bs.top != bs.base) { //将结点右孩子设为空,代表已访问其右孩子 root.rchild = NULL; pop(&bs); push(&bs, root); //右孩子入栈 root = *temp; push(&bs, root); traverseStack(bs); visitNode(&root); } } } //************************************************************************************ // 主函数 //************************************************************************************ void main() { BiTree Tree = createBiTree(); printf("n二叉树先序遍历结果如下n"); preTraverse(Tree); printf("nn栈中结点变化情况如下n"); for(int i = 0; i < cnt; i++) { printf("栈中的结点有:"); int j = 0; while(stack[i][j] != 0xFFFFFFFF) { printf("%d ", stack[i][j]); j++; } printf("n"); } printf("nn"); system("date /T"); system("TIME /T"); system("pause"); exit(0); }
运行结果:
4 Python实现算法1代码:
import datetime
import time
##################################################################################
# 二叉树
##################################################################################
#树结点类
class BiNode():
#创建结点,左右孩子为空
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None
#创建左右孩子结点
def creat(self, data1=0xFFFFFFFF, data2=0xFFFFFFFF):
if data1 != 0xFFFFFFFF:
self.lchild = BiNode(data1)
if data2 != 0xFFFFFFFF:
self.rchild = BiNode(data2)
#创建一棵简单的二叉树
def creatTree():
T = BiNode(1)
T.creat(2, 3)
T.lchild.creat(4, 5)
T.rchild.creat(6, 7)
return T
#############################################################################################
# 栈
#############################################################################################
#栈类
class Stack():
def __init__(self):
self.bs = []
def push(self, e):
self.bs.append(e)
def pop(self):
if self.bs:
return self.bs.pop()
else:
raise LookupError("stack is empty!")
def getTop(self):
return self.bs[-1]
####################################################################################
# 使用栈结构先序遍历二叉树
####################################################################################
time = 0 #记录访问结点次数
#访问结点的操作
def visitNode(node):
global time #将time设为全局变量
time += 1
print("第{}次访问的结点是:{}".format(time, node.data))
stackList = [] #记录栈中元素,列表的每个元素也为列表
#遍历栈,栈中结点的数据存储在stackList中
def traverseStack(treeStack):
global stackList
temp = []
for i in range(len(treeStack.bs)):
temp.append(treeStack.bs[i].data)
stackList.append(temp)
#先序遍历二叉树
def preTraverse(T):
treeStack = Stack()
traverseStack(treeStack)
treeStack.push(T)
traverseStack(treeStack)
visitNode(T)
while treeStack.bs != []: #栈空代表遍历结束
root = treeStack.getTop()
temp = root.lchild
while temp != None:
#左孩子入栈
treeStack.push(temp)
traverseStack(treeStack)
visitNode(temp)
#将结点左孩子设为空,代表已访问其左孩子
root.lchild = None
root = temp
temp = root.lchild
temp = root.rchild #后访问右孩子
while temp == None: #右孩子为空,代表左右孩子均已访问,结点可以出栈
treeStack.pop() #结点出栈
traverseStack(treeStack)
if treeStack.bs == []: #根结点出栈,遍历结束
break
#查看上一级结点是否访问完左右孩子
root = treeStack.getTop()
temp = root.rchild
if treeStack.bs != []:
treeStack.push(temp) #右孩子入栈
traverseStack(treeStack)
visitNode(temp)
root.rchild = None #将结点右孩子设为空,代表已访问其右孩子
if __name__ == '__main__':
T = creatTree()
print("n二叉树先序遍历结果如下")
preTraverse(T)
print("n栈中结点变化情况如下")
for i in range(len(stackList)):
print("栈中的结点有:{}".format(stackList[i]))
print("nn")
datetime = datetime.datetime.now()
print(datetime.strftime("%Y-%m-%dn%H:%M:%S"))
运行结果:



