zoukankan      html  css  js  c++  java
  • c语言数据结构:递归的替代-------回溯算法

    1.要理解回溯就必须清楚递归的定义和过程。

      递归算法的非递归形式可采用回溯算法。主要考虑的问题在于:

    1. 怎样算完整的一轮操作。
    2. 执行的操作过程中怎样保存当前的状态以确保以后回溯访问。
    3. 怎样返回至上一次未执行的操作。

    2.贴代码表现:

    先序遍历二叉树:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "stackar.h"
    #include "fatal.h"
    char U[100];
    typedef struct TreeNode {
    	ElementType Element;
    	struct TreeNode *Left;
    	struct TreeNode *Right;
    } BTNode;
    BTNode *FindNode(BTNode *b,ElementType x)
    {
    //在二叉树中查找值为x的结点
    	BTNode *p;
    	if (b==NULL)   return NULL;
    	else if (b->Element==x)   return b;
    	else
    	{
    		p=FindNode(b->Left,x);
    		if (p!=NULL) return p;
    		else   return FindNode(b->Right,x);
    	}
    }
    BTNode *CreateTree(BTNode *root)
    {
    //先序递归创建二叉树,
    //输入范例:abd#g##e##cf#h###
    //对应于:  a(b(d(,g),e),c(f(,h),))
    	char ch;
    	scanf("%c",&ch);
    	if(ch=='#') {
    		//printf("--%c$$$
    ",ch);
    		return NULL;
    	}
    	else
    	{
    		//printf("++%c***
    ",ch);
    		root=(BTNode *)malloc(sizeof(BTNode));
    		root->Element=ch;
    		root->Left=CreateTree(root->Left);
    		root->Right=CreateTree(root->Right);
    	}
    	return root;
    }
    int pd(BTNode *b)
    {
        if(b->Left==NULL&&b->Right==NULL)
            return 0;
        if(b->Left!=NULL&&b->Right==NULL)
            return 1;
        if(b->Left==NULL&&b->Right!=NULL)
            return 2;
        if(b->Left!=NULL&&b->Right!=NULL)
            return 3;
    }
    void prev(BTNode *b)
    {
        BTNode *f=b;
        int i,j;
        U[0]='|';
        i=1;
        for(;;)
        {
            for(;;)
            {
                j=0;
                printf("%c",f->Element);
                switch(pd(f))
                {
                case 0: {                                  //当一个节点为叶子结点的时候开始回溯
                         j=1;break;
                }
                case 1:{
                         f=f->Left;break;                  //当一个节点有左孩子无右孩子的时候访问左孩子
                }
                case 2:{
                         f=f->Right;break;                 //当一个节点有右孩子无左孩子的时候访问右孩子
                }
                case 3:{
                         U[i++]=f->Element;                //当一个节点有左孩子又有右孩子时存入节点的值
                         f=f->Left;break;                  //至字符数组U,以便以后回溯访问上一级。与此同时继续访问左孩子
                }
    
                }
                if(j==1)
                    break;
            }
            f=FindNode(b,U[i-1]);                            //根据U中最近保存的字符找出在原二叉树中相应的结点
            if(--i==0)
            break;
            f=f->Right;                                     //此时,应该访问回溯节点的右节点                                          //弹栈操作
        }
    }
    void main()
    {
        BTNode *T,*p;
    	T=CreateTree(p);
        prev(T);
    
    }
    

      

      

  • 相关阅读:
    Spring用代码来读取properties文件
    单链表与双链表的区别
    为什么有些IP无法PING通但又能访问
    使用iperf3调试网络
    arm linux 移植 iperf3
    ZYNQ:PetaLinux工程更新HDF文件的脚本
    ZYNQ:使用PetaLinux打包 BOOT.BIN、image.ub
    ZYNQ:提取PetaLinux中Linux和UBoot配置、源码
    ZYNQ:使用 PetaLinux 构建Linux项目
    ZYNQ:使用SDK打包BOOT.BIN、烧录BOOT.BIN到QSPI-FLASH
  • 原文地址:https://www.cnblogs.com/akiradunn/p/5002105.html
Copyright © 2011-2022 走看看