数据结构经典算法总复习(下卷)

第五章:树和二叉树

先序遍历二叉树的非递归算法。

void PreOrderTraverse(BiTree T, void (*Visit)(TElemType)) {//表示用于查找的函数的指针
  Stack S; BiTree p = T;
  InitStack(S);//S模拟工作栈
  while (p || !StackEmpty(S)) {//S为空且下一个结点为空,意味着结束遍历
    if (p) {//p有值,则Push进栈为一个工作进程
      Visit(p->data); Push(S, p); p = p->lchild;//先序遍历,先Visit
    } else {
//p为空,则它的上级被Pop出去,成为新的p,再取右孩子。在下一个循环中如果它的上级没右孩子,则说明它的上级是叶子结点(或两端已经工作栈弹出了),则再Pop出它的上级的上级(此时它的上级已经无用,工作栈弹出),取它上级的兄弟结点
      Pop(S, p); p = p->rchild;
    }
  }
}

利用工作栈的思想,过程十分复杂,多多复习,巩固加深!

层序遍历二叉树

void LayerTraverse(BiTree T, void (*Visit)(TElemType)) {
  Queue Q; BiTree p;
  InitQueue(Q);
  EnQueue(Q, T);
  while (!QueueEmpty(Q)) {
    DeQueue(Q, p);
//每有一个父母结点出队列,就把它的左右孩子放到队尾排队,确保一层一层遍历
    if (p) {
      Visit(p->data);
      EnQueue(Q, p->lchild); EnQueue(Q, p->rchild);
    }
  }
}

计算二叉树中每个结点的层次

void LevelRecur(BiTree T, int lev) {
  if (T) {
    ++lev;//准备遍历下一层
    cout << T->data << ' ' << lev << endl;
    LevelRecur(T->lchild, lev);
    LevelRecur(T->rchild, lev);//下一层启动
  }
}
void Level(BiTree T) {
  LevelRecur(T, 0);
}

输出二叉树根结点到所有叶子结点的路径 

void OutPath(BiTree T, Stack &S) {//使用一个栈存储路径,起到回溯的作用
  if (T) {
    Push(S, T);
    if (!T->lchild && !T->rchild)
      PrintStack(S);//S栈中元素依次输出,不取出
    OutPath(T->lchild, S);
    OutPath(T->rchild, S);
    Pop(S, T);//该节点左右孩子搜索完,则出栈,不再计入路径中
  }
}

由扩展的先序序列,即波兰式,建立二叉树 

void CreateBiTree(BiTree &T) {
  // 读入扩展的先序序列,假定数据元素为字符型,#表示NULL
  char ch; scanf("%c", &ch);
  if (ch == '#') T = NULL;
  else {
    T = new BiTNode; T->data = ch;
    CreateBiTree(T->lchild);//依次建立二叉树
    CreateBiTree(T->rchild);
  }
}

先根遍历树,孩子链表实现

void PreOrderRecur(CTree T, int loc, void (*Visit)(TElemType)) {
  if (loc == -1) return;
  Visit(T.nodes[loc].data);//先查询根结点
  ChildPtr p;
  for (p = T.nodes[loc].firstchild; p; p = p->next) {
    PreOrderRecur(T, p->child, Visit);//取出下个孩子,并查询
  }
}
void PreOrderTree(CTree T, void (*Visit)(TElemType)) {
  PreOrderRecur(T, T.root, Visit);
}

计算树的深度,孩子兄弟链表实现

int TreeDepth(CSTree T) {
  if (!T) return 0;//最简单情况,遍历结束条件
  CSTree p; int maxh = 0;//maxh为全局变量
  for (p = T->firstchild; p; p = p->nextsibling) {//到T的下一个孩子,并且遍历其孩子的兄弟
    int h = TreeDepth(p);//当前遍历结点的深度
    if (h > maxh) maxh = h;
  }
  return maxh + 1;
}

构造huffman树

typedef unsigned int WeightType;
typedef struct {
  TElemType data;
  WeightType weight; // 叶子权值的类型
  int parent, lchild, rchild; // 三叉静态链表
} HTNode, *HuffmanTree;
void CreateHuffmanTree(HuffmanTree &HT, int n) {
  int m = 2*n-1; // 最终将得到2n-1个结点
  HT = new HTNode[m];
  for (i=0; i<n; ++i) {
    cin >> HT[i].data >> HT[i].weight;
    HT[i].lchild = HT[i].rchild = HT[i].parent = -1;//-1即示意为为null
  }//输入结点值
  for (i=n; i<m; ++i) {
    Select(HT, i-1, s1, s2); HT[s1].parent=HT[s2].parent=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值