陈越《数据结构》第七讲 图中

Tree Traversals Again

1086.Tree Traversals Again (25)
An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example,suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed,the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

Input Specification:

Each input file contains one test case. For each case,the first line contains a positive integer N (<=30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow,each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

Output Specification:

For each test case,print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space,and there must be no extra space at the end of the line.

Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
Sample Output:
3 4 2 6 5 1

题目大意
用栈的形式给出一棵二叉树的建立的顺序,求这棵二叉树的后序遍历
分析:栈实现的是二叉树的中序遍历(左根右),而每次push入值的顺序是二叉树的前序遍历(根左右),所以该题可以用二叉树前序和中序转后序的方法做~~

#include <cstdio>
#include <stack>
using namespace std;

int preorder[35],inorder[35];
int n,preid = 0,inid = 0,cnt = 0;
int get(){
    char s[10];
    scanf("%s",s);
    if (s[1] == 'o') return -1;
    int a;
    scanf("%d",&a);
    return a;
}
void build(int preb,int pree,int inb,int ine){
    if (preb > pree) return;
    int root = preorder[preb];
    int inroot = inb;
    while (inorder[inroot] != root) ++inroot;
    build(preb+1,preb+inroot-inb,inb,inroot-1);
    build(preb+inroot-inb+1,pree,inroot+1,ine);
    if (cnt++ != 0) putchar(' ');
    printf("%d",root);
}
int main(){
    scanf("%d",&n);
    stack<int> st;
    for (int i = 0; i < n*2; ++i){
        int a = get();
        if (a != -1){
            st.push(a);
            preorder[preid++] = a;
        }else{
            inorder[inid++] = st.top();
            st.pop();
        }
    }
    build(0,n-1,0,n-1);
    return 0;
}

Complete Binary Search Tree

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
Both the left and right subtrees must also be binary search trees.
A Complete Binary Tree (CBT) is a tree that is completely filled,with the possible exception of the bottom level,which is filled from left to right.

Now given a sequence of distinct non-negative integer keys,a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

Input Specification:

Each input file contains one test case. For each case,the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.

Output Specification:

For each test case,print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space,and there must be no extra space at the end of the line.

Sample Input:
10
1 2 3 4 5 6 7 8 9 0
Sample Output:
6 3 8 1 5 7 9 0 2 4

题意
给一串构成树的序列,已知该树是完全二叉搜索树,求它的层序遍历的序列
分析
总得概括来说,已知中序,可求root下标,可以求出层序。
1. 因为二叉搜索树的中序满足:是一组序列的从小到大排列,所以只需排序所给序列即可得到中序
2. 因为根据完全二叉树的结点数,可以求出它的根结点在中序中对应的下标
3. 如此,已知了中序,又可以根据结点数求出根结点的下标,就可以递归求出左右子树的根结点的下标
4. i结点的左孩子为2 * i + 1,右孩子2 * i + 2,就可以根据结点下标和中序数组赋值level数组
5. 最后输出所有结点的层序数组level


图1

图2

图3

#include <cstdio>
#include <cstdlib>
#include <math.h>

const int MaxNum = 1005;
int node[MaxNum];
int tree[MaxNum];

int cmp(const void *a,const void *b)
{/*以图2为基准*/
    int *pa = (int *)a;
    int *pb = (int *)b;
    return *pa-*pb;
}
int GetLeftLength(int n)
{/*以图3为基准*/
    int h,x,l;
    /*转换成以2为底*/
    h = log((double)(n + 1))/log (2.0);
    x = n + 1 - pow(2.0,h);
    if (x > pow(2.0,h - 1)) {
        x = pow(2.0,h - 1);
    }
    l = pow(2.0,h - 1) - 1 + x;
    return l;
}

void solve(int ALeft,int ARight,int TRoot)
{/*初始调用为solve(0,N-1,0)*/
/*以图1为基准*/
    int n,L,LeftTRoot,RightTRoot;
    n = ARight - ALeft + 1;
    if(n==0) return;        /*考虑完美二叉树的情况*/
    L = GetLeftLength(n);    /*计算出n个节点的树,其左子树有多少个节点*/
    tree[TRoot] = node[ALeft + L];
    LeftTRoot = TRoot * 2 + 1;
    RightTRoot = LeftTRoot + 1;
    solve(ALeft,ALeft + L -1,LeftTRoot);
    solve(ALeft + L + 1,ARight,RightTRoot);

}

int main()
{
    int i,n;
    /*输入*/
    scanf("%d",&n);
    for(i=0;i<n;++i){
        scanf("%d",&node[i]);
    }
    /*从大到小排序*/
    qsort(node,n,sizeof(int),cmp);
    /*排序成完全二叉树*/
    solve(0,0);
    /*输出*/
    printf("%d",tree[0]);
    for(i=1;i<n;++i){
        printf(" %d",tree[i]);
    }
    printf("\n");
    system("pause");
    return 0;
}

Huffman Codes

PTA - Data Structures and Algorithms (English) - 5-9

In 1953,David A. Huffman published his paper “A Method for the Construction of Minimum-Redundancy Codes”,and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes,I am encountering a big problem: the Huffman codes are NOT unique. For example,given a string "aaaxuaxz" ,we can observe that the frequencies of the characters a,x,uandz are 4 , 2 , 1 and 1 ,respectively. We may either encode the symbols as a=0,x=10,u=110,z=111 ,or in another way as a=1,x=01,u=001,z=000 ,both compress the string into 14 bits. Another set of code can be given as a=0,x=11,u=100,z=101 ,but a=0,x=01,u=011,z=001 is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001 . The students are submitting all kinds of codes,and I need a computer program to help me determine which ones are correct and which ones are not.

Input Specification:

Each input file contains one test case. For each case,the first line gives an integer N (2N63) ,then followed by a line that contains all the N distinct characters and their frequencies in the following format:

c[1],f[1],c[2],f[2],...c[N],f[N]
where c[i] is a character chosen from {'0'-'9','a'-'z','A'-'Z','_'},and f[i] is the frequency of c[i] and is an integer no more than 1000 . The next line gives a positive integer M (≤1000),then followed by M student submissions. Each student submission consists of N lines,each in the format:

c[i],code[i]
where c[i] is the ith character and code [i] is an non-empty string of no more than 63 ‘0’s and ‘1’s.

Output Specification:

For each test case,print in each line either “ Yes ” if the student’s submission is correct,or “ No ” if not.

Note: The optimal solution is not necessarily generated by Huffman algorithm . Any prefix code with code length being optimal is considered correct.

Sample Input:
7 //结点数目num
A 1 B 1 C 1 D 3 E 3 F 6 G 6 //每个结点数据data及出现的次数weight
4 //测试数据的组数checkNum
A 00000 //之后的 4*7行 是结点数据ch及其编码s
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11
Sample Output:
Yes
Yes
No
No

题目分析

这是一道考察“哈夫曼编码”的问题,但是这里不一定非要把哈夫曼树构造出来。Note: The optimal solution is not necessarily generated by Huffman algorithm
- 输入:第一行是结点数目num;第二行是每个结点数据data及出现的次数weight;第三行是测试数据的组数checkNum;第四行及以后是结点数据ch及编码s。

  • 输出:对于每一组测试数据,输出编码是否符合“哈夫曼编码”,是则输出Yes,否则输出No。

  • 符合“哈夫曼编码”需要符合两个条件:
    WPL

例1:最优编码不一定通过Huffman算法得到。给定4个字符及其出现频率: A:1;B:1;C:2;D:2 。下面哪一套不是用Huffman算法得到的正确的编码?
A. A:000; B:001; C:01; D:1
B. A:10; B:11; C:00; D:01
C. A:00; B:10; C:01; D:11
D. A:111; B:001; C:10; D:1
解析:C
根据答案,画出每个答案的Huffman tree,再一个个的对答案是否正确。

例2Huffman Codes的特点:

  1. 最优编码 —— 总长度(WPL)最小;
  2. 无歧义解码 —— 前缀码:数据仅存于叶子结点;
  3. 没有度为1 的结点 —— 123
    注意 231 !比如:

解法:

解法转自:http://www.cnblogs.com/clevercong/p/4193370.html
1) map 用于存放:A 1 B 1 C 1 D 3 E 3 F 6 G 6 //每个结点的数据data及出现的次数(权值)weight

2) 使用C++标准库中的优先队列:priority_queue,引入头文件 #include 。优先队列底层由堆实现,数据放入队列后,会自动按照“优先级”排好顺序。

#include <map>
#include <queue>

map<char,int> myMap;
priority_queue<int,vector<int>,greater<int> >pq;  //小顶堆

for(int i=0; i<num; i++)  // 输入结点的数据c[i]、权值f[i]
{
    cin >> c[i] >> f[i];
    myMap[c[i]] = f[i];  // 映射
    pq.push(f[i]);  // 向队列中添加元素
}

3) 计算 WPL 的值,从priority_queue中取出两个元素,相加之后再放回队列里。

// 计算WPL的值
int myWpl = 0;
while(!pq.empty())
{
    int myTop = pq.top();
    pq.pop();
    if(!pq.empty())
    {
        int myTop2 = pq.top();
        pq.pop();
        pq.push(myTop + myTop2);
        int m = myTop + myTop2;
        myWpl += m;  //每次加m(子节点权值重复加入) 等效于 路径长度*权值
    }
}

4) 测试数据需按编码排序,但标准库并没有为map制定sort函数,因此我们用vector装载pair类型,既可以模仿出map的功能,又可以用vector的排序函数。

#include <algorithm> // sort()
typedef pair<char,string> PAIR;  // 用PAIR来代替pair<char,string> (编码类型:string)

// cmp():自定义按什么内容或大小顺序排序
// 这里是按编码的长度排序
int cmp(const PAIR& x,const PAIR& y)
{
    return x.second.size() < y.second.size();
}
// vector + pair<,> 模仿 map
vector<PAIR> checkVec;
checkVec.push_back(make_pair(ch,s));  // 向vector中添加元素
sort(checkVec.begin(),checkVec.end(),cmp);  // 按照编码的长度排序

5) 判断前缀问题:substr函数,取字符串中的一段并与当前编码进行比较。

bool flag = true;  //已符合条件一:wpl最小
for(int i=0; i<num; i++)
{
    string tmp = checkVec[i].second;
  for(int j=i+1; j<num; j++)
    {
        if(checkVec[j].second.substr(0,tmp.size())==tmp)
            flag = false;
    }
}

完整代码

#include <iostream>
#include <algorithm> // 排序函数 sort()
#include <map>
#include <queue>
using namespace std;

typedef pair<char,string> PAIR;  // + vector来模仿 map

int cmp(const PAIR& x,const PAIR& y)  // 自定义让sort()按哪种方式排序
{
    return x.second.size() < y.second.size();
}

int main()
{
    int num;
    cin >> num;
    char *c = new char[num];
    int *f = new int[num];
    map<char,int> myMap;  // 用来存节点数据及权值,并构成映射
    // 使用优级队列
    priority_queue<int,greater<int> >pq;

    for(int i=0; i<num; i++)  // 输入结点及出现次数(权值)
    {
        cin >> c[i] >> f[i];
        myMap[c[i]] = f[i];
        pq.push(f[i]);  // 将权值压入优先队列
    }
    // 计算WPL的值
    int myWpl = 0;
    while(!pq.empty())
    {
        int myTop = pq.top();
        pq.pop();
        if(!pq.empty())
        {
            int myTop2 = pq.top();
            pq.pop();
            pq.push(myTop + myTop2);
            int m = myTop + myTop2;
            myWpl += m;
        }
    }
    // 输入测试数据
    int checkNum;  // 测试数据的组数
    cin >> checkNum;
    for(int i=0; i<checkNum; i++)
    {
        int wpl = 0;
        char ch;
        string s;
        // vector + PAIR 模仿 map,使其可排序
        vector<PAIR> checkVec;
        for(int j=0; j<num; j++)
        {
            cin >> ch >> s;
            checkVec.push_back(make_pair(ch,s));  // 向vector中添加测试数据及其编码
            wpl += s.size() * myMap[ch];
        }
        sort(checkVec.begin(),cmp);  // 按照编码长度排序
        if(wpl != myWpl)
        {
            cout << "No" << endl;
            continue;
        }
        else
        {
            bool flag = true;  // 表示已满足条件一:wpl最小(wpl==myWpl)

            //条件二:编码的前缀不能是其他编码的前缀:substr()
            for(int i=0; i<num; i++)
            {
                string tmp = checkVec[i].second;
                for(int j=i+1; j<num; j++)
                {
                    if(checkVec[j].second.substr(0,tmp.size())==tmp)
                        flag = false;
                }
            }
            if(flag == true)
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
            continue;
        }
        cout << "Yes" << endl;
    }
    return 0;
}

总结的程序

#include <iostream>
#include <string>
using namespace std;
struct Heap
{
    int *data;
    int size = 0;
};
struct cnode
{
    int tag = 0;
    cnode *left = nullptr;
    cnode *right = nullptr;
};

Heap *Init_Heap(int n); //初始化小根堆(利用静态链表的逻辑结构);
void Insert_Heap(Heap *H,int x);   //把元素依次插入小根堆;
int Delmin_Heap(Heap *H);   //删除小根堆中的最小元素;
int Cal_Wpl(Heap *H);   //计算huffman编码的wpl;
int wpl_prefix(int *sample,int n,int &re);    //计算待测编码的wpl及判断是否为前缀编码;

/*思路:要判断是否,需要解决两个问题: 1)编码wpl等于huffman编码的wpl; 2)待测编码是前缀编码。 问题1: 首先要求出标准wpl。观察huffman树,我们发现其wpl是非叶子结点权值和。 于是,我们无需构造出huffman树来求权值(麻烦点),通过模拟树的构造过程, 理由小根堆的特点求出wpl; 而待测编码的wpl就是利用每个编码的字符串长度,乘以每个字符的权值得到; 问题2: 思路是构造一个二叉树出来,模拟huffman树。 1.让每个编码遍历树,结束时在当前结点设置标记为1; 2.如果遍历时,未结束时碰到了标记为1的结点,则不是前缀编码; 3.结束时,未碰到标记点(包括最后一个),是前缀编码。 */
int main()
{
    int n,i,val;
    char ch;
    cin >> n;
    int *sample = new int[n];   //每个字符权值存储在这里;
    Heap *H = Init_Heap(n); //初始化小根堆(利用静态链表的逻辑结构);
    for (i = 0; i < n; i++)
    {
        cin >> ch >> val;
        sample[i] = val;
        Insert_Heap(H,val);    //把元素依次插入小根堆;
    }
    int best_wpl = Cal_Wpl(H);  //计算huffman编码的wpl;

    int m,wpl,re; //re是用来判断是否前缀编码,是为1,否为0;
    cin >> m;
    for (i = 0; i < m; i++)
    {
        wpl = wpl_prefix(sample,re);    //计算待测编码的wpl及判断是否为前缀编码;
        if (wpl == best_wpl && re == 1)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
    delete sample;

    return 0;
}

Heap *Init_Heap(int n)
{
    Heap *H = new Heap;
    H->data = new int[n + 1];   //堆的下标从1开始(为了操作方便);
    H->data[0] = -1;    //小根堆赋值最小值;

    return H;
}

void Insert_Heap(Heap *H,int x)    //把元素依次插入小根堆;
{
    int i = ++(H->size);
    for (; H->data[i / 2] > x; i /= 2)  //从下往上过滤;
        H->data[i] = H->data[i / 2];
    H->data[i] = x;

    return;
}

int Delmin_Heap(Heap *H)    //删除小根堆中的最小元素;
{
    int t = H->data[H->size--];
    int min = H->data[1];
    int pa,chi;
    for (pa = 1; pa * 2 <= H->size; pa = chi)   //从上往下过滤最小元素;
    {
        chi = pa * 2;
        if (chi != H->size && H->data[chi + 1] < H->data[chi])  //找到子结点的最小下标;
            chi++;
        if (t < H->data[chi])
            break;
        else
            H->data[pa] = H->data[chi];
    }
    H->data[pa] = t;    //赋值最小元素

    return min;
}

int Cal_Wpl(Heap *H)    //计算huffman编码的wpl;
{
    int sum = 0;
    if (H->size > 1)
    {
        int i,t1,t2,t;
        int m = H->size;
        for (i = 1; i < m; i++)
        {
            t1 = Delmin_Heap(H);    //模拟构造huffman树的过程,先取出两个最小值,相加,把和插入堆中;
            t2 = Delmin_Heap(H);
            t = t1 + t2;
            Insert_Heap(H,t);
            sum += t;
        }
    }
    else
        sum = H->data[0];

    return sum;
}

int wpl_prefix(int *sample,int &re) //计算待测编码的wpl及判断是否为前缀编码;
{
    int i,j,len,wpl = 0;
    char ch;
    string st;
    cnode *phead = new cnode;
    cnode *p = phead;
    re = 1;
    for (i = 0; i < n; i++)
    {
        cin >> ch >> st;    //此处计算wpl;
        len = st.length();
        wpl += len*sample[i];

        if (re != 0)    //此处判断是否前缀编码;
        {
            for (j = 0; j < len; j++)
            {
                if (st[j] == '0')   //0的话判断左边;
                {
                    if (p->left == nullptr) //左边空,新建结点;
                    {
                        cnode *q = new cnode;
                        p->left = q;
                    }
                    else
                    {
                        if (p->tag == 1)
                        {
                            re = 0;
                            break;
                        }
                    }
                    p = p->left;
                }
                else if (st[j] == '1')  //判断右边;
                {
                    if (p->right == nullptr)
                    {
                        cnode *q = new cnode;
                        p->right = q;
                    }
                    else
                    {
                        if (p->tag == 1)
                        {
                            re = 0;
                            break;
                        }
                    }
                    p = p->right;
                }
            }

            if (p->left == nullptr && p->right == nullptr)
                re = 1;
            else
                re = 0;
            if (p->tag == 0)    //注意此处需要判断,最后结点标记不为1才能赋值(待测编码有可能有相同的);
                p->tag = 1;
            else
                re = 0;

            p = phead;
        }
    }

    return wpl;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


【啊哈!算法】算法3:最常用的排序——快速排序       上一节的冒泡排序可以说是我们学习第一个真正的排序算法,并且解决了桶排序浪费空间的问题,但在算法的执行效率上却牺牲了很多,它的时间复杂度达到了O(N2)。假如我们的计算机每秒钟可以运行10亿次,那么对1亿个数进行排序,桶排序则只需要0.1秒,而冒泡排序则需要1千万秒,达到115天之久,是不是很吓人。那有没有既不浪费空间又可以快一点的排序算法
匿名组 这里可能用到几个不同的分组构造。通过括号内围绕的正则表达式就可以组成第一个构造。正如稍后要介绍的一样,既然也可以命名组,大家就有考虑把这个构造作为匿名组。作为一个实例,请看看下列字符串: “08/14/57 46 02/25/59 45 06/05/85 18 03/12/88 16 09/09/90 13“ 这个字符串就是由生日和年龄组成的。如果需要匹配年两而不要生日,就可以把正则
选择排序:从数组的起始位置处开始,把第一个元素与数组中其他元素进行比较。然后,将最小的元素方式在第0个位置上,接着再从第1个位置开始再次进行排序操作。这种操作一直到除最后一个元素外的每一个元素都作为新循环的起始点操作过后才终止。 public void SelectionSort() { int min, temp;
public struct Pqitem { public int priority; public string name; } class CQueue { private ArrayList pqueue; public CQueue() { pqueue
在编写正则表达式的时候,经常会向要向正则表达式添加数量型数据,诸如”精确匹配两次”或者”匹配一次或多次”。利用数量词就可以把这些数据添加到正则表达式里面了。 数量词(+):这个数量词说明正则表达式应该匹配一个或多个紧紧接其前的字符。 string[] words = new string[] { "bad", "boy", "baad", "baaad" ,"bear", "b
来自:http://blog.csdn.net/morewindows/article/details/6678165/归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列
插入排序算法有两层循环。外层循环会啄个遍历数组元素,而内存循环则会把外层循环所选择的元素与该元素在数组内的下一个元素进行比较。如果外层循环选择的元素小于内存循环选择的元素,那么瘦元素都想右移动以便为内存循环元素留出位置。 public void InsertionSort() { int inner, temp;
public int binSearch(int value) { int upperBround, lowerBound, mid; upperBround = arr.Length - 1; lowerBound = 0; while (lowerBound <= upper
虽然从表内第一个节点到最后一个节点的遍历操作是非常简单的,但是反向遍历链表却不是一件容易的事情。如果为Node类添加一个字段来存储指向前一个节点的连接,那么久会使得这个反向操作过程变得容易许多。当向链表插入节点的时候,为了吧数据复制给新的字段会需要执行更多的操作,但是当腰吧节点从表移除的时候就能看到他的改进效果了。 首先需要修改Node类来为累增加一个额外的链接。为了区别两个连接,这个把指
八、树(Tree)树,顾名思义,长得像一棵树,不过通常我们画成一棵倒过来的树,根在上,叶在下。不说那么多了,图一看就懂:当然了,引入了树之后,就不得不引入树的一些概念,这些概念我照样尽量用图,谁会记那么多文字?树这种结构还可以表示成下面这种方式,可见树用来描述包含关系是很不错的,但这种包含关系不得出现交叉重叠区域,否则就不能用树描述了,看图:面试的时候我们经常被考到的是一种叫“二叉树”的结构,二叉
Queue的实现: 就像Stack类的实现所做的一样,Queue类的实现用ArrayList简直是毋庸置疑的。对于这些数据结构类型而言,由于他们都是动态内置的结构,所以ArrayList是极好的实现选择。当需要往队列中插入数据项时,ArrayList会在表中把每一个保留的数据项向前移动一个元素。 class CQueue { private ArrayLis
来自:http://yingyingol.iteye.com/blog/13348911 快速排序介绍:快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地
Stack的实现必须采用一种基本结构来保存数据。因为再新数据项进栈的时候不需要担心调整表的大小,所以选择用arrayList.using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Collecti
数组类测试环境与排序算法using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Data_structure_and_algorithm{ class CArray { pr
一、构造二叉树 二叉树查找树由节点组成,所以需要有个Node类,这个类类似于链表实现中用到的Node类。首先一起来看看Node类的代码。 public class Node { public int Data; public Node Left; public Node Right; public v
二叉树是一种特殊的树。二叉树的特点是每个结点最多有两个儿子,左边的叫做左儿子,右边的叫做右儿子,或者说每个结点最多有两棵子树。更加严格的递归定义是:二叉树要么为空,要么由根结点、左子树和右子树组成,而左子树和右子树分别是一棵二叉树。 下面这棵树就是一棵二叉树。         二叉树的使用范围最广,一棵多叉树也可以转化为二叉树,因此我们将着重讲解二叉树。二叉树中还有连两种特殊的二叉树叫做满二叉树和
上一节中我们学习了队列,它是一种先进先出的数据结构。还有一种是后进先出的数据结构它叫做栈。栈限定只能在一端进行插入和删除操作。比如说有一个小桶,小桶的直径只能放一个小球,我们现在向小桶内依次放入2号、1号、3号小球。假如你现在需要拿出2号小球,那就必须先将3号小球拿出,再拿出1号小球,最后才能将2号小球拿出来。在刚才取小球的过程中,我们最先放进去的小球最后才能拿出来,而最后放进去的小球却可以最先拿
msdn中的描述如下:(?= 子表达式)(零宽度正预测先行断言。) 仅当子表达式在此位置的右侧匹配时才继续匹配。例如,w+(?=d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。(?(零宽度正回顾后发断言。) 仅当子表达式在此位置的左侧匹配时才继续匹配。例如,(?此构造不会回溯。msdn描述的比较清楚,如:w+(?=ing) 可以匹配以ing结尾的单词(匹配结果不包括ing),(
1.引入线索二叉树 二叉树的遍历实质上是对一个非线性结构实现线性化的过程,使每一个节点(除第一个和最后一个外)在这些线性序列中有且仅有一个直接前驱和直接后继。但在二叉链表存储结构中,只能找到一个节点的左、右孩子信息,而不能直接得到节点在任一遍历序列中的前驱和后继信息。这些信息只有在遍历的动态过程中才能得到,因此,引入线索二叉树来保存这些从动态过程中得到的信息。 2.建立线索二叉树 为了保
排序与我们日常生活中息息相关,比如,我们要从电话簿中找到某个联系人首先会按照姓氏排序、买火车票会按照出发时间或者时长排序、买东西会按照销量或者好评度排序、查找文件会按照修改时间排序等等。在计算机程序设计中,排序和查找也是最基本的算法,很多其他的算法都是以排序算法为基础,在一般的数据处理或分析中,通常第一步就是进行排序,比如说二分查找,首先要对数据进行排序。在Donald Knuth 的计算机程序设