树、二叉树、查找算法总结

1.思维导图

2.重要概念的笔记

1.二叉树的递归遍历

void PreorderPrintLeaves( BinTree BT ){
    if(BT!=NULL){
            printf(" %c",BT->Data);
            PreorderPrintLeaves( BT->Left );
            PreorderPrintLeaves(  BT->Right );}
    }
}

2.二叉树的层次遍历

void Levelorder(BiTree BT) {
    BiTree p;
    BTqueue q;
    int i = 0;
    if (BT == NULL) {
        cout << "NULL";
        return;
    }
    Crequeue(q);
    Enqueue(q, BT);
    while (!Emptyqueue(q)) {
        Dequeue(q, p);
        if (i)cout << " ";
        i = 1;
        cout << p->data ;
        if (p->lchild != NULL) {
            Enqueue(q, p->lchild);
        }
        if (p->rchild != NULL) {
            Enqueue(q, p->rchild);
        }
    }
}

3.二叉树的非递归遍历

void PreOrder(BTree BT) {//非递归先序遍历
    BTStack* st;
    BTree p;
    InitStack(st);
    p = BT;
    while (!EmptyStack(st) || p != NULL) {
        while (p != NILL) {
            cout << p->data;
            Push(st, p);
            p = p->lchild;
        }
        if (!EmptyStack(st)) {
            Pop(st, p);
            p = p->rchild;
        }
    }
}

4.二叉树的构造

BTree creat(int a, int b, int n)//前序遍历和中序遍历构建二叉树
{
	BTree T;
	int i;
    int c;
	if (n <= 0) T = NULL;
	else
	{
		T = new BTNode;
		T->data = s1[a];
		for (i = 0;s1[a] != s2[b + i];i++);
        c=a+i;
		T->lchild = creat(a + 1, b, i);
		T->rchild = creat(c+ 1, b + i + 1, n - i - 1);
	}
	return T;
}

5.哈夫曼树的算法实现

void CreateHT(HTNode ht[], int n, float s[]) {
    int i, j, k, l, r;
    float min1, min2;
    for (i = 0; i < n; i++) {
        ht[i].data = s[i];
    }
    for (i = n; i < 2 * n - 1; i++) {
        min1 = min2 = 32767;
        r = l = -1;
        for (k = 0; k < i; k++) {
            if (ht[k].parent == -1) {
                if (ht[k].data < min1) {
                    min2 = min1;
                    r = l;
                    min1 = ht[k].data;
                    l = k;
                }
                else if (ht[k].data < min2) {
                    min2 = ht[k].data;
                    r = k;
                }
            }
        }
        ht[i].data = ht[l].data + ht[r].data;
        ht[i].l = l;
        ht[i].r = r;
        ht[l].parent = ht[r].parent = i;
    }
}

6.二叉排序树的构建,插入,查找与删除

InsertBST(T, key) {
    if (T为空) {
        创建T;
        T->data = key;
        T的左孩子 = T的右孩子 = 空;
        return;
    }
    else if (T->data = key)
        return;
    else if (key < T->data)
        InsertBST(T->lchild, key);
    else if (key > T->data)
        InsertBST(T->rchild, key);
}

int InsertBST(BTree& BT, int k) {
    if (BT == NULL) {
        BT = new BTNode;
        BT->data = k;
        BT->lchild = BT->rchild = NULL;
        return 1;
    }
    else if (BT->data == k) {
        return 0;
    }
    else if (k < BT->data) {
        return InsertBST(BT->lchild, k);
    }
    else
        return InsertBST(BT->rchild, k);
}
BTree SearchBST(BTree BT, int k) {
    if (BT == NULL || BT->data == k)
        return BT;
    if (k < BT->data)
        return SearchBST(BT->lchild, k);
    else
        return SearchBST(BT->rchild, k);
}
void DeleteBST(BTree & BT) {
    BTree q, s;
    if (BT->lchild == NULL) {
        q = BT;
        BT = BT->rchild;
        delete q;
    }
    else if (BT->rchild == NULL) {
        q = BT;
        BT = BT->lchild;
        delete q;
    }
    else {
        q = BT;
        s = BT->lchild;
        while (s->rchild) {
            q = s;
            s = s->rchild;
        }
        BT->data = s->data;
        if (q == BT)
            BT->lchild = s->lchild;
        else
            q->rchild = s->lchild;
        delete s;
    }
}

7.二叉平衡树的插入

需要辨别不平衡的最低节点进行调整,观察插入失衡情况进行左左,右右,左右,右左的旋转调整二叉树的平衡。

8.哈希表的构造以及哈希冲突的解决方法

使用直接定址法、除留余数法或者数字分析法进行哈希表的创建排列,当发生哈希冲突时,可使用顺序表的线性探测法和平方探测法,或者使用链表的拉链法将每个单元存放同义词单链表的头指针。

3.疑难问题及解决方案

1.根据后序和中序遍历输出先序遍历

#include<iostream>
#include<string>

using namespace std;

int s1[30];
int s2[30];
typedef struct HTNode {
    int data;
    struct HTNode* lchild, * rchild;
}HTNode, * HTree;

HTree CreateHT(int a,int b, int n);
void PrintHT(HTree HT);
int main() {
    int n, i;
    cin >> n;
    HTree HT;
    HT = new HTNode;
    for (i = 0; i < n; i++) {
        cin >> s1[i];
    }
    for (i = 0; i < n; i++) {
        cin >> s2[i];
    }
    HT=CreateHT(n - 1, 0, n);
    cout << "Preorder:";
    PrintHT(HT);
}
HTree CreateHT(int a, int b, int n) {
    HTree T;
    int i;
    if (n <= 0)T= NULL;
    else {
        T = new HTNode;
        T->data = s1[a];
        for (i = 0; s2[b + i] != s1[a]; i++);
        T->lchild = CreateHT(a-n+i , b, i);
        T->rchild = CreateHT(a - 1 , b + i + 1, n - 1 - i);
    }
    return T;
}
void PrintHT(HTree HT) {
    if (HT != NULL) {
        cout << " " << HT->data;
        PrintHT(HT->lchild);
        PrintHT(HT->rchild);
    }
}

该题可以与根据先序遍历和中序遍历创建二叉树联系起来,做一些方位上的修改,就可以比较轻松的完成

2.输出二叉树每层节点

#include<iostream>
#include<string>
#include<queue>

using namespace std;

typedef struct BTNode {
    char data;
    int h;
    struct BTNode* lchild, * rchild;
}BTNode,*BTree;

BTree CreateTree(string s, int& i,int h);
void PrintTree(BTree BT);

int main() {
    string s;
    int i = 0;
    cin >> s;
    if(s.size()==0)
        cout<<"NULL";
    else{
        BTree BT;
        BT = CreateTree(s, i,1);
        if (BT == NULL)cout << "NULL";
        else {
            PrintTree(BT);
        }
    }
}
BTree CreateTree(string s, int& i,int h) {
    BTree BT;
    if (i >= s.size())return NULL;
    if (s[i] == '#')return NULL;
    BT = new BTNode;
    BT->data = s[i];
    BT->h = h;
    h++;
    BT->lchild = CreateTree(s, ++i,h);
    BT->rchild = CreateTree(s, ++i,h);
    return BT;
}
void PrintTree(BTree BT) {
    queue<BTree>q;
    BTree p;
    int i = 1;
    q.push(BT);
    cout << i << ":";
    while (!q.empty()) {
        p = q.front();
        if (p->h != i) {
            cout << "\n";
            i++;
            cout << i << ":";
        }
        cout << p->data << ",";
        q.pop();
        if (p->lchild != NULL)
            q.push(p->lchild);
        if (p->rchild != NULL) {
            q.push(p->rchild);
        }
    }
}

灵活使用层次遍历

3.二叉树的线索化如何实现

简而言之就是当该节点非头结点时,若左孩子为空,则左指针指向前驱节点,若右孩子为空,则右指针指向后继节点。在遍历线索二叉树时,若找不到后继节点,则寻找右孩子节点的最左孩子节点,否则就跟随后继节点,直到后继节点指向头结点。

4.哈夫曼树

目前找不到中间两个测试点出错的原因在哪

#include<iostream>
#include<string>

using namespace std;

#define MAX 20000
typedef struct HTNode {
    float data;
    int l = -1;
    int r = -1;
    int parent = -1;
}HTNode, * HTree;

void CreateHT(HTNode ht[], int n, float s[]);
float Count(HTNode ht[], int n);
int main() {
    int n, i;
    cin >> n;
    float s[10000];
    for (i = 0; i < n; i++) {
        cin >> s[i];
    }
    HTNode ht[MAX];
    HTree head;
    CreateHT(ht, n, s);
    cout << Count(ht, n);
}

void CreateHT(HTNode ht[], int n, float s[]) {
    int i, j, k, l, r;
    float min1, min2;
    for (i = 0; i < n; i++) {
        ht[i].data = s[i];
    }
    for (i = n; i < 2 * n - 1; i++) {
        min1 = min2 = 32767;
        r = l = -1;
        for (k = 0; k < i; k++) {
            if (ht[k].parent == -1) {
                if (ht[k].data < min1) {
                    min2 = min1;
                    r = l;
                    min1 = ht[k].data;
                    l = k;
                }
                else if (ht[k].data < min2) {
                    min2 = ht[k].data;
                    r = k;
                }
            }
        }
        ht[i].data = ht[l].data + ht[r].data;
        ht[i].l = l;
        ht[i].r = r;
        ht[l].parent = ht[r].parent = i;
    }
}
float Count(HTNode ht[], int n) {
    int i;
    float sum = 0;
    for (i = 0; i < 2*n-2; i++) {
        sum += ht[i].data ;
    }
    return sum;
}
posted @ 2020-04-25 21:13  字圣大人  阅读(242)  评论(0)    收藏  举报