数据结构(严版)课本代码重敲——第六章

编程笔记 数据结构 第六章 树与二叉树

以后有什么知识盲点就记录一下, 经常拿出来复习才能彻底消化吸收,一个劲儿地往前学是不可行的方法。

typedef struct 和struct

1 首先://注意在C和C++里不同
    在C中定义一个结构体类型要用typedef:

typedef struct Student
    {
    int a;
    }Stu;

于是在声明变量的时候就可:Stu stu1;(如果没有typedef就必须用struct Student stu1;来声明)
    这里的Stu实际上就是struct Student的别名。Stu==struct Student
    另外这里也可以不写Student(于是也不能struct Student stu1;了,必须是Stu stu1;)

typedef struct
    {
    int a;
    }Stu;

但在c++里很简单,直接

struct Student
    {
    int a;
    };  

于是就定义了结构体类型Student,声明变量时直接Student stu2;

2.其次:
    在c++中如果用typedef的话,又会造成区别:

struct   Student   
    {   
    int   a;   
    }stu1;//stu1是一个变量  

typedef   struct   Student2   
    {   
    int   a;   
    }stu2;//stu2是一个结构体类型=struct Student  

使用时可以直接访问stu1.a
    但是stu2则必须先 stu2 s2;
    然后 s2.a=10;

引用和指针

一、引用的定义

引用是给另外一个变量起别名,所以引用不会分配内存空间。

引用的声明方法:类型标识符 &引用名=目标变量名;(如int &ptr = num;)

二、引用与指针的区别

1、指针是一个实体,需要分配内存空间。引用只是变量的别名,不需要分配内存空间。

2、引用在定义的时候必须进行初始化,并且不能够改变。指针在定义的时候不一定要初始化,并且指向的空间可变。(注:不能有引用的值不能为NULL)

3、有多级指针,但是没有多级引用,只能有一级引用。

4、指针和引用的自增运算结果不一样。(指针是指向下一个空间,引用时引用的变量值加1)

5、sizeof 引用得到的是所指向的变量(对象)的大小,而sizeof 指针得到的是指针本身的大小。

6、引用访问一个变量是直接访问,而指针访问一个变量是间接访问。



#include <iostream>

using namespace std;

void swap(int &a, int &b)
{
	int tmp;

	tmp = a;
	a   = b;
	b   = tmp;
}

int main()
{
	int a = 3;
	int b = 5;

	cout << "before swap, a = " << a << " b = " << b << endl;

	swap(a, b);
	
	cout << "after swap, a = " << a << " b = " << b << endl;

    return 0;
}


#### 3/24 二叉树练习

引用是给变量了另一个名字,调用时为直接调用变量而指针是分配了一个内存空间并存下变量的地址,属于间接引用。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;

/*
    题目:二叉树
    1. 二叉树的创建
    2. 四种遍历方法
    3. 三种非递归遍历方法
*/
typedef char Elemtype;
typedef struct node
{
    struct node *lchild;
    struct node *rchild;
    Elemtype data;
}BiNode, *BiTree;
// 给结构体node起别名:BiNode,以及结构体的指针的别名:BiTree

void create(BiTree &t)
{
    Elemtype x;
    cin >> x;
    if (x == '#')
    {
        t = NULL;
    }
    else
    {
        t = (BiTree)malloc(sizeof(BiTree));
        t->data = x;
        create(t->lchild);
        create(t->rchild);
    }
}

void print(BiTree &t)
{
    if (t != NULL)
    {
        cout << t->data ;
        print(t->lchild);
        print(t->rchild);
    }
}
// 1. 表达式求值 输入一个表达式创建二叉树

void createBD(BiTree &t)
{
    Elemtype x;
    cin >> x;
    if (x != '#')
    {
        t = (BiTree )malloc(sizeof(BiTree));
        t->data = x;
        createBD(t->lchild);
        createBD(t->rchild);
    }else
    {
        t = NULL;
    }
}

int cmp(int a,char op,int b)
{
    switch (op)
    {
        case '+':return a+b;
        case '-':return a-b;
        case '*':return a*b;
        case '/':
            if (b!=0)
                return a/b;
    }
    return 0;
}
// 后序遍历计算值
int countV(BiTree &t)
{
    int a,b;

    if (t!=NULL)
    {
        if (t->lchild == NULL && t->rchild == NULL)
        {
            return t->data - '0';
        }
        else
        {
            a = countV(t->lchild);
            b = countV(t->rchild);
            int c = cmp(a,t->data,b);
            return c;
        }
    }
    else
        return 0;
}

int depth(BiTree &t)
{
    if (t == NULL)
        return 0;
    else
    {
        int l = depth(t->lchild);
        int r = depth(t->rchild);
        return l>=r?l+1:r+1;
    }

}
// 层次遍历
void level(BiTree &t)
{
    queue<BiTree> q;
    BiTree p;
    if (t) // 空树没有必要遍历了
    {
        q.push(t); // 根节点入队
        while (!q.empty())
        {
           p =  q.front(); // 弹栈一个元素
           q.pop();
            cout << p->data << ' ';

            if (p->lchild)
            {
                q.push(p->lchild);
            }
            if (p->rchild)
            {
                q.push(p->rchild);
            }
        }
    }
}
// 计算二叉树的宽度
struct Node{
BiTree t;
int num; // 结点所在的层次号
};
const int maxSize = 100;
int width(BiTree &t)
{
    Node q[maxSize];
    int front , rear ;
    front = rear = 0;
    int mm;

    BiTree p;
    Node n;
    if (t) // 空树没有必要遍历了
    {
        n.t = t;
        n.num = 1;
        rear = (rear+1)%maxSize;
        q[rear] = n;
        while (front != rear)
        {
           front = (front +1)%maxSize;
           p = q[front].t;
          // cout << p->data << ' ';
            int lno = q[front].num;
            if (p->lchild)
            {
                n.num = lno +1;
                n.t = p->lchild;
                rear = (rear +1)%maxSize;
                q[rear] = n;
            }
            if (p->rchild)
            {
                n.num = lno + 1;
                n.t = p->rchild;
                rear = (rear +1)%maxSize;
                q[rear] = n;
            }
        }


        mm = 0;

        for (int i=1;i<=n.num;i++)
        {
            int nn = 0 ;
            for (int j=1;j<=rear;j++)
                if (q[j].num == i)
                    ++nn;

            if (nn > mm)
                mm = nn;
        }
        return mm;
        }
        else return 0;
    }

// 非递归遍历算法
// 先序遍历
void preOrderNon(BiTree &t)
{
    BiTree s[maxSize];
    BiTree p;
    int top = -1;
    if (t)
    {
        s[++top] = t;
        //cout << t->data << endl;
        while (top != -1)
        {
            p = s[top--];
            cout << p->data << ' ';
            if (p->lchild)
            {
                s[++top] = p->lchild;
            }
            if (p->rchild)
            {
                s[++top] = p->rchild;
            }
        }
    }
}

// 中序遍历
void inOrderNon(BiTree &t)
{
    BiTree s[maxSize];
    int top = -1;
    BiTree p;
    p = t;
    if (t){
    while (p!=NULL || top != -1)
    {
        while (p)
        {
            s[++top] = p;
            p = p->lchild;
        }
        if (top!=-1)
        {
            p = s[top--];
            cout << p->data << ' ';
            p = p->rchild;
        }
    }
    }
}
// 后序遍历


int main()
{
    BiTree t;
    //create(t);
    createBD(t);
   // width(t);
    //int c = countV(t);
    //cout << c << endl;
   // print(t);
   // cout << width(t)<<endl;
    inOrderNon(t);
    return 0;
}

二叉树练习 2018/3/26
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;

/*
    题目:二叉树
1. 创建二叉树 √
2. 三种递归遍历方法+层次遍历法 √
3. 三种非递归遍历方法
4. 求二叉树的深度
6. 求叶子结点的个数
8. 求先序遍历中第K个结点的值
9. 左右子树互换
10.复制二叉树
7. 表达式求值
5. 求二叉树的宽度
*/
typedef char Elemtype;
typedef struct BiNode
{
    Elemtype data;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

// 1. 先序创建二叉树
void createBiTree(BiTree &t)
{
    // 输入一个字符串序列,为NULL的指针表示为#
    Elemtype x;
    cin >> x;
    if ( x == '#')
    {
        t = NULL;
    }
    else
    {
        t = (BiTree )malloc(sizeof(BiTree));
        t->data = x;
        createBiTree(t->lchild);
        createBiTree(t->rchild);
    }
}

// 2. 先序递归遍历

// 访问函数
void visited(BiTree p)
{
    cout <<p ->data <<' ';
}
void preOrderTraverse(BiTree &t)
{
    if (t)
    {
        visited(t);
        preOrderTraverse(t->lchild);
        preOrderTraverse(t->rchild);
    }
}

// 2. 层次遍历需要队列的辅助,没有递归遍历方法
/*
1. 初始化队列
2. 压入根之前判断根是否为空
3. 取队头 -> 访问结点 -> 压入非空的左孩子和右孩子
4. 队列为空时循环结束
*/
void levelOrder(BiTree &t)
{
    queue<BiTree> que ;
    BiTree p = t; // p : 遍历指针
    if (t) // 根节点不能为空
    {
        que.push(t);
        while (!que.empty())
        {
             p = que.front();
             que.pop();
             visited(p);
             if (p->lchild)
             {
                 que.push(p->lchild);
             }
             if (p->rchild)
             {
                 que.push(p->rchild);
             }
        }
    }
}

// 3. 非递归三种遍历方法

// 先序非递归
/*
1. 遇到一个结点首先访问该结点,如果有左子树则继续往左走
2. 到了最左边时弹栈,访问右子树
3. 如果右子树为空则继续弹栈,否则向右子树的左边继续前进
*/
void preOrderUn(BiTree &t)
{
    stack<BiTree> st;
    BiTree p = t;
    while (p!= NULL || !st.empty()) // 当且仅当栈和指针都为空时循环结束
    {
        while (p)
        {
            visited(p);
            st.push(p);
            p = p->lchild;
        }
        if (!st.empty())
        {
            p = st.top();
            st.pop();
            p = p->rchild;
        }
    }
}
// 中序非递归
void midOrderUn(BiTree t)
{
    stack<BiTree> st;
    BiTree p = t;
    while (p != NULL || !st.empty())
    {
        while(p)
        {
            st.push(p);
            p = p->lchild;
        }
        if (!st.empty())
        {
            p  = st.top();
            st.pop();
            visited(p);
            p = p->rchild;
        }
    }
}
// 后序非递归遍历
/*
1. 第一次访问结点:入栈,isFirst = 1
2. 弹栈如果isFirst == 1,修改isFirst,压栈,往右走
3. 第三次访问如果isFirst = 0,访问结点数据
*/
typedef struct lBiTree
{
    BiTree t;
    int isFirst;
}lBiTree;
void lastOrderUn(BiTree t)
{
    stack<lBiTree> st;
    BiTree p = t;
    lBiTree l;
    while ( p!=NULL || !st.empty())
    {
        while (p)
        {
            l.isFirst = 1;
            l.t = p;
            st.push(l);
            p = p->lchild;
        }
        if (!st.empty())
        {
            l = st.top();
            st.pop();

            if (l.isFirst == 1)
            {
                l.isFirst = 0;
                p = l.t->rchild;
                st.push(l);
            }
            else
            {
                visited(l.t);
                p = NULL;
            }
        }
    }
}
// 4. 深度
int depth(BiTree t)
{
    if (t == NULL)
        return 0;
    else
    {
        int l = depth(t->lchild);
        int r = depth(t->rchild);
        return l >= r?l+1:r+1;
    }
}

// 求叶子结点个数
int leaf(BiTree t)
{
    if (t)
    {
        if (t->lchild == NULL && t->rchild == NULL)
        {
            return 1;
        }
        else
        {
            return leaf(t->lchild)+leaf(t->rchild);
        }
    }
    else
        return 0;
}

// 求树的结点个数
int number(BiTree t)
{
    if (t)
        return 0; //空树没有结点
    else{
        return 1+number(t->lchild)+number(t->rchild);
    }
}
// 左右子树互换
void exchange(BiTree &t)
{
    BiTree s;
    if (t)
    {
        s = t->lchild;
        t->lchild = t->rchild;
        t->rchild = s;
        exchange(t->lchild);
        exchange(t->rchild);
    }

}
// 复制二叉树
BiTree copyBiTree(BiTree &t)
{
    BiTree p;
    if (t)
    {
        p = (BiTree)malloc(sizeof(BiTree));
        p->data = t->data;
        p->lchild = copyBiTree(t->lchild);
        p->rchild = copyBiTree(t->rchild);
        return p;
    }

}

// 表达式求值
int countValue(BiTree t)
{
    if (t)
    {
        if (t->lchild == NULL &&t->rchild == NULL)
        {
            return t->data-'0';
        }
        else{
            int a = countValue(t->lchild);
            int b = countValue(t->rchild);
            int c = cmp(a,t->data,b);
            return c;
        }
    }
}


int main()
{
    BiTree t;
    createBiTree(t);
   // preOrderTraverse(t);
   // levelOrder(t);
  // preOrderUn(t);
  //midOrderUn(t);
 // lastOrderUn(t);
 //cout << depth(t)<<endl;
 cout << leaf(t)<<endl;
    return 0;
}

3/29 日练习
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;

/*
    时间:2018/3/26
    题目:二叉树
1. 创建二叉树 √
2. 三种递归遍历方法+层次遍历法 √
3. 三种非递归遍历方法 √
4. 求二叉树的深度 √
5. 求叶子结点的个数 √
6. 求先序遍历中第K个结点的值 √
7. 左右子树互换 √
8.复制二叉树 √
9. 表达式求值 √
10. 求二叉树的宽度 √
11.线索二叉树的中序线索化
12.线索二叉树的中序遍历
13.线索二叉树的先序、后序线索化以及遍历方法
*/
typedef char Elemtype;
typedef struct BiNode
{
    Elemtype data;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;
void createBiTree(BiTree &t)
{
    Elemtype x;
    cin >> x;
    if (x!='#')
    {
        t = (BiTree )malloc(sizeof(BiTree));
        t->data = x;
        createBiTree(t->lchild);
        createBiTree(t->rchild);
    }
    else
    {
        t = NULL;
    }
}
void visit(BiTree p)
{
    cout << p->data <<' ';
}
void preOrder(BiTree &t)
{
    if (t)
    {
        visit(t);
        preOrder(t->lchild);
        preOrder(t->rchild);
    }
}
void levelOrder(BiTree &t)
{
    queue<BiTree> que;
    BiTree p = t;
    if (t)
    {
        que.push(p);
        while (!que.empty()) // 注意这里队空时结束,而不是队和P指针都为空,到最后的时候P不为空
        {
            p = que.front();
            que.pop();
            visit(p);
            if (p->lchild!=NULL)
                que.push(p->lchild);
            if (p->rchild!=NULL)
                que.push(p->rchild);
        }
    }
}
void preOrderUn(BiTree &t)
{
    stack<BiTree> st;
    BiTree p = t;
    if (t)
    {
        while (p || !st.empty())
        {
            while (p)
            {
                visit(p);
                st.push(p);
                p = p->lchild;
            }
            if (!st.empty())
            {
                p = st.top();
                st.pop();
                p = p->rchild;
            }
        }
    }
}
typedef struct
{
    BiTree k;
    int isFirst;
}PBiTree;
void postOrderUn(BiTree &t)
{
    stack<PBiTree> st;
    BiTree p  = t;
    PBiTree tmp;
    if (t)
    {
        while (p || !st.empty())
        {
            while (p)
            {
                tmp.isFirst = 1;
                tmp.k = p;
                st.push(tmp);
                p = p->lchild;
            }
            if (!st.empty())
            {
                tmp = st.top();
                st.pop();
                if (tmp.isFirst == 1)
                {
                    tmp.isFirst = 0;
                    st.push(tmp);
                    p = tmp.k->rchild;
                }else
                {
                    visit(tmp.k);
                    p = NULL;
                }
            }
        }
    }
}
int depth(BiTree &t)
{
    if (t->lchild == NULL && t->rchild == NULL)
    {
        return 1;
    }
    if (t)
    {
        int l = depth(t->lchild);
        int r = depth(t->rchild);
        return l>r?l+1:r+1;
    }
}
int leaf(BiTree &t)
{
    if (t->lchild == NULL && t->rchild == NULL)
        return 1;
    if (t)
    {
        return leaf(t->lchild)+leaf(t->rchild);
    }
}
void exchange(BiTree &t)
{
    BiTree p;
    if (t)
    {
        p = t->lchild;
        t->lchild = t->rchild;
        t->rchild = p;
        exchange(t->lchild);
        exchange(t->rchild);
    }
}
int count(int a,char c,int b)
{
    return 1;
}
int value(BiTree &t)
{
    if (t->lchild == NULL && t->rchild == NULL)
    {
            return t->data -'0';
    }
    if (t)
    {
        int a = value(t->lchild);
        int b = value(t->rchild);
        int c = count(a,t->data,b);
        return c;
    }
}
typedef struct
{
    BiTree k;
    int level;
}WBiTree;
const int MAXSIZE  = 20;
int width(BiTree &t)
{
    WBiTree que[MAXSIZE];
    BiTree p = t;
    WBiTree tmp,tmp2;
    int front=0,rear = 0;
    int level = 1;
    if (t)
    {
        rear = (rear+1)%MAXSIZE;
        tmp.k = p;
        tmp.level = level;
        que[rear] = tmp;
        while (front != rear)
        {
            front = (front+1)%MAXSIZE;
            tmp = que[front];
            if (tmp.k->lchild)
            {
                rear = (rear+1)%MAXSIZE;
                tmp2.k = tmp.k->lchild;
                tmp2.level = tmp.level+1;
                que[rear] = tmp2; // 等于根节点+1
            }
            if (tmp.k->rchild)
            {
                rear = (rear+1)%MAXSIZE;
                tmp2.k = tmp.k->rchild;
                tmp2.level = tmp.level+1;
                que[rear] = tmp2; // 等于根节点+1
            }
        }
        // 遍历一下que数组,从0-rear,统计每层的结点个数,求最大值
        int maxNum = 0;
        int num = 1;
        int j = 1;
        for (int i = 1;i<=rear;i++)
        {

            if (que[i+1].level == que[i].level)
            {
                num++;
            }
            else
            {
                num = 1;
            }
            if (num > maxNum)
            {
                maxNum = num;
            }
        }
        return maxNum;
    }
    return 0;
}
int main()
{
    BiTree t;
    createBiTree(t);
//    preOrder(t);
//    levelOrder(t);
//    preOrderUn(t);
//postOrderUn(t);
//cout << depth(t) << endl;
//cout << leaf(t) << endl;
cout << width(t) << endl;

    return 0;
}

数据结构》(C语言版) 算法源码及运行演示系统使用说明 一、启动演示系统 双击演示系统应用程序文件“DS_VC_ALGO.EXE”启动演示系统,出现图1所示界面。 图1 《数据结构》(C语言版)算法源码及运行演示系统主界面 二、演示系统使用步骤 除了个别算法之外,演示系统给出了《数据结构》(C语言版)书中算法对应的程序代码(CPP文件)和测试运行程序(VC++6.0的EXE文件)。通过本系统,可以显示算法的源代码以及运行结果。具体操作步骤如下: 1.选择相应章 单击演示系统界面右侧章选择按钮。 例如,要选择第6章,则单击“第6章”选择按钮。 当相应章被选择后,窗口的右侧部分将列出本章的算法选择按钮。 例如,选择第6章后,窗口的右侧部分将显示第6章中的算法6.1-6.13和6.15的选择按钮。由于书中的算法6.14和6.16只是示意性算法,故未给出源码,其按钮上的文字为灰色,处于“无效”状态。 2.选择相应章中的算法 单击窗口右侧部分所列举的本章某个算法选择按钮,被选择的算法的源码将在窗口左侧空白区域中显示。对于较长的源码,单击显示区域后,可用键盘的光标键和翻页键浏览源码。 例如,选择了第6章中的算法6.5后界面如图2所示: 图2 选择算法6.5 3.运行测试程序 单击窗口上部的“运行”按钮,将弹出运行窗口,运行所选算法的测试程序。若运行按钮为灰色,表示该算法无单独测试程序。 例如,算法6.5的测试运行窗口如图3所示: 图3 测试运行窗口 测试运行说明: 测试运行窗口显示程序的执行过程及结果。若在显示过程中出现运行窗口无法正常演示的情况,只需调节运行窗口大小即可正常显示(调节最小化按钮或窗口最大化/还原按钮“ ”)。 三、退出演示系统 使用完毕后,单击窗口右上角关闭按钮“ ”退出演示系统。 四、测试程序示例 在《数据结构》的课程教学中,各抽象数据类型的设计与实现是重要的学习和实践环节。为此,本系统只给出了各算法源码的测试程序的可执行文件。在此,给出算法6.5的测试程序示例,以供参考。 算法6.5是中序遍历线索二叉树的非递归算法,要对其源码进行测试,可首先调用算法6.6及6.7建立中序线索二叉树。以下是测试程序的源码,相关类型和辅助函数定义在文件include06.h和include06.cpp中,此略。 // test0605.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "include06.h" // 相关类型和辅助函数的定义 BiThrTree pre; // 线索二叉树遍历辅助变量 #include "algo0607.cpp" // 算法6.7源码 #include "algo0606.cpp" // 算法6.6源码 #include "algo0605.cpp" // 算法6.5源码 int main(int argc, char* argv[]) { char gl_str[64]; BiThrTree T; BiThrTree Thrt; printf("*******************************************\n"); printf("* 《数据结构》(C语言版)严蔚敏,吴伟民 *\n"); printf("* 算法6.5, 6.6 & 6.7 *\n"); printf("*******************************************\n"); srand((unsigned)time(NULL)); // 随机函数初始化 T=NULL; // 空二叉树T for (int pass=0; pass<5; pass++) { // 测试运行5次,第一次为空树 outBiThrTree(T,gl_str); // 以类广义表的形式输出二叉树T到gl_str printf("T = %s\n", gl_str); // 显示 pre = NULL; Status r = InOrderThreading(Thrt, T); // 算法6.6,6.7,中序线索化 printf("InOrderThreading(Thrt, T) : %s\n", (r) ? "OK" : "ERROR"); initVisitStr(); // 将visitStr清为空串 InOrderTraverse_Thr(Thrt, v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值