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


    编程笔记 数据结构 第九十章

    二叉搜索树

      1 #include <iostream>
      2 #include <string.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <stack>
      6 using namespace std;
      7 /*
      8     日期:2018/4/17
      9     题目:二叉搜索树
     10 */
     11 typedef int Elemtype;
     12 typedef struct BSTNode
     13 {
     14     int key;
     15     Elemtype data;
     16     struct BSTNode *lchild,*rchild;
     17 }BSTNode,*BSTree;
     18 
     19 // 1 创建时插入建立二叉搜索树
     20 void insertBSTree(BSTree &t,BSTree &p)
     21 {
     22 
     23     if (t == NULL)
     24     {
     25         t = p; // 根节点为空
     26     }
     27     else {
     28         if (p->data >= t->data)
     29             insertBSTree(t->rchild,p);
     30         else
     31             insertBSTree(t->lchild,p);
     32     }
     33 
     34 
     35 }
     36 void createBSTree(BSTree &t)
     37 {
     38     Elemtype x;
     39     BSTree p;
     40     int n ;
     41     cout<< "请输入N和待排序的数据"<< endl;
     42     cin >> n;
     43     for (int i = 0;i<n;i++)
     44     {
     45         cin >> x;
     46         p = (BSTree)malloc(sizeof(BSTNode));
     47         p->data = x;
     48         p->key = i+1;
     49         p->lchild = NULL;
     50         p->rchild = NULL;
     51         insertBSTree(t,p);
     52     }
     53 
     54 }
     55 // 中序遍历
     56 void inOrder(BSTree t)
     57 {
     58     if (t)
     59     {
     60        inOrder(t->lchild);
     61        cout << t->data << " ";
     62        inOrder(t->rchild);
     63     }
     64 }
     65 
     66 // 查找
     67 int searchBSTree(BSTree &t,Elemtype data)
     68 {
     69     if (t)
     70     {
     71         if (data == t->data)
     72             return t->key;
     73         else if (data > t->data)
     74             searchBSTree(t->rchild,data);
     75         else
     76             searchBSTree(t->lchild,data);
     77     }else
     78     return 0;
     79 }
     80 // 动态树表:树结构不是一次生成的,而是在查找过程中,当树中不存在关键字等于
     81 // 给定值得结点时再进行插入,新插入的结点一定是叶子结点。
     82 
     83 int searchBSTree_dynamic(BSTree t,Elemtype data,BSTree &p,BSTree &f)
     84 {
     85     if (t)
     86     {
     87         if (t->data == data)
     88         {
     89             p = t;
     90             return 1;
     91         }
     92         else
     93         {
     94             if (t->data > data)
     95                 searchBSTree_dynamic(t->lchild,data,p,t);
     96             else
     97                 searchBSTree_dynamic(t->rchild,data,p,t);
     98         }
     99 
    100     }
    101     else
    102     {
    103         p = f;
    104         return 0;
    105     }
    106 
    107 }
    108 void insertBSTree_dynamic(BSTree &t,Elemtype data)
    109 {
    110     BSTree p=NULL,f = NULL; // p指向查找到的结点,f为未找到是时的父节点
    111     BSTree s;
    112     if (!searchBSTree_dynamic(t,data,p,f))
    113     {
    114         s = (BSTree)malloc(sizeof(BSTNode));
    115         s->data = data;
    116         s->lchild = NULL;
    117         s->rchild = NULL;
    118         // 在树中没找到时即要插入结点
    119         if (p == NULL)
    120         {
    121             t = s; // t为空二叉树,插入的叶子结点即为根节点的特殊情况
    122         }
    123         else
    124         {
    125             if (data > p->data )
    126                 p->rchild = s;
    127             else
    128                 p->lchild = s; // 插入新的叶子结点
    129         }
    130 
    131     }
    132 }
    133 
    134 /*
    135 删除节点分为三种情况:
    136 1 p的左右子树均空,直接修改父节点指针
    137 2 p有一个子树,让该子树成为父节点的左子树
    138 3 p的两个子树均不为空
    139 递归找到该结点,然后删除
    140 
    141 */
    142 
    143 void deleteBST(BSTree &t,Elemtype data)
    144 {
    145     void deleteB(BSTree&);
    146     if (t)
    147     {
    148         if (t->data == data)
    149         {
    150             deleteB(t);
    151         }
    152         else if (t->data > data)
    153             deleteBST(t->lchild,data);
    154         else
    155             deleteBST(t->rchild,data);
    156     }
    157 }
    158 int deleteB(BSTree &p)
    159 {
    160     BSTree q,s;
    161     if (p->lchild == NULL &&p->rchild == NULL)
    162     {
    163         q = p;
    164         p = NULL;
    165         free(q);
    166     }
    167     else
    168         if (p->lchild == NULL)
    169         { // 只有左子树空
    170             q = p;
    171             p = p->rchild;
    172             free(q);
    173         }
    174         else  // 只有右子树空
    175         if (p->rchild == NULL)
    176         {
    177             q = p;
    178             p = p->lchild;
    179             free(q);
    180         }
    181         else // 均不空
    182         {
    183            s = p->lchild;
    184            while (s->rchild!=NULL)
    185                 s = s->rchild;
    186            s ->rchild = p->rchild;
    187            q = p;
    188            p = p->lchild;
    189            free(q);
    190         }
    191 }
    192 // delete 和 free 的的区别?
    193 int main()
    194 {
    195     BSTree t = NULL;
    196     //createBSTree(t);
    197     int n;
    198     Elemtype x;
    199     cout << "n" << endl;
    200     cin >> n ;
    201     for (int i=0;i<n;i++)
    202     {
    203         cin >> x;
    204         insertBSTree_dynamic(t,x);
    205     }
    206     inOrder(t);
    207     cout << "请输入要删除的数据" <<endl;
    208     cin >> x;
    209     deleteBST(t,x);
    210     inOrder(t);
    211 
    212 
    213     return 0;
    214 }

    二叉搜索树的复习

      1 #include <iostream>
      2 #include <string.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <stack>
      6 using namespace std;
      7 /* 二叉搜索树 复习
      8 1. 创建+插入
      9 2. 搜索
     10 3. 删除
     11 4. 遍历
     12 */
     13 
     14 typedef struct BSTNode
     15 {
     16     int key;
     17     struct BSTNode *lchild,*rchild;
     18 }BSTNode,*BSTree;
     19 
     20 int insertBSTree(BSTree &t,BSTree &p)
     21 {
     22     // 如果找到则返回指向关键字的指针,否则插入到树中
     23     if (t== NULL)
     24     {
     25         t = p;
     26         return 1;
     27     }else
     28     {
     29         if (t->key == p->key)
     30         {
     31             return 1;
     32         }else if (t->key > p->key)
     33             insertBSTree(t->lchild,p);
     34         else
     35             insertBSTree(t->rchild,p);
     36     }
     37 }
     38 void createBSTree(BSTree &t)
     39 {
     40     t = NULL;
     41     int n;
     42     cout << "请输入N:" <<endl;
     43     cin >> n;
     44     cout << "请输入N个数" << endl;
     45     int key;
     46     for (int i=0;i<n;i++)
     47     {
     48         cin >> key;
     49         BSTree p = (BSTree)malloc(sizeof(BSTNode));
     50         p->key = key;
     51         p->lchild = NULL;
     52         p->rchild  = NULL;
     53         insertBSTree(t,p);
     54     }
     55 }
     56 
     57 void preOrder(BSTree T)
     58 {
     59     if (T)
     60     {
     61         preOrder(T->lchild);
     62         cout << T->key << " ";
     63         preOrder(T->rchild);
     64     }
     65 }
     66 
     67 void deleteT(BSTree &p)
     68 {
     69     BSTree q;
     70     // 删除P指向的结点
     71     if (p->lchild == NULL && p->rchild == NULL )
     72     {
     73         q = p;
     74         p = NULL;
     75         free(q);
     76         return ;
     77     }
     78     if (p->lchild == NULL)
     79     {
     80         q = p;
     81         p = p->rchild;
     82         free(q); // free 和 delete 的区别
     83         // malloc - free C new - delete C++
     84     }
     85     else if (p->rchild == NULL)
     86     {
     87         q = p;
     88         p = p ->lchild;
     89         free(q);
     90     }
     91     else
     92     {
     93         // 左右子树均不为空时,P左子树的最右侧的结点+P的右子树
     94         BSTree s = p->lchild;
     95         while (s->rchild != NULL)
     96             s = s->rchild;
     97         s->rchild = p->rchild;
     98         q = p;
     99         p = p->lchild;
    100         free(q);
    101 
    102     }
    103 }
    104 void deleteBSTNode(BSTree &t,int key)
    105 {
    106     if (t)
    107     {
    108         // t为空时则为未找到
    109         if (t->key == key)
    110             deleteT(t);
    111         else if (t->key > key)
    112             deleteBSTNode(t->lchild,key);
    113         else
    114             deleteBSTNode(t->rchild,key);
    115     }
    116 
    117 }
    118 int main()
    119 {
    120     BSTree t;
    121     createBSTree(t);
    122     preOrder(t);
    123     cout << "key:" << endl;
    124     int key;
    125     cin >> key;
    126     deleteBSTNode(t,key);
    127     preOrder(t);
    128 
    129 
    130     return 0;
    131 }

    哈希表的实现

     1 #include <iostream>
     2 #include <string.h>
     3 #include <stdio.h>
     4 #include <stdlib.h>
     5 #include <stack>
     6 #define SUCCESS 1
     7 #define UNSUCCESS -1
     8 #define NULLkey -65519
     9 
    10 
    11 using namespace std;
    12 /*
    13 哈希表
    14 */
    15 const int HashLength = 20;
    16 typedef int Elemtype;
    17 typedef struct
    18 {
    19     Elemtype *elem;
    20     int count; // 当前元素个数
    21 }HashTable;
    22 
    23 void initHashTable(HashTable &h)
    24 {
    25     h.elem = (Elemtype *)malloc(sizeof(Elemtype)*HashLength);
    26     h.count = 0;
    27     for (int i = 0;i<HashLength;i++)
    28         h.elem[i] = NULLkey;
    29 }
    30 
    31 int hash_f(int key)
    32 {
    33     return key%HashLength;
    34 }
    35 void insertHashTable(HashTable &h,int key)
    36 {
    37     int addr = hash_f(key);
    38     while (h.elem[addr]!= NULLkey)
    39     {
    40         addr = (addr+1)%HashLength;
    41     }
    42     h.elem[addr] = key;
    43     h.count++;
    44 }
    45 int searchHashTable(HashTable h,int key)
    46 {
    47     // 查找成功返回存储位置否则返回UNSUCCESS
    48     int addr = hash_f(key);
    49     while (h.elem[addr]!=key)
    50     {
    51         addr = (addr+1)%HashLength;
    52         if (h.elem[addr] == NULLkey || addr == hash_f(key))
    53             return UNSUCCESS;
    54         // 如果线性探测再散列到NULLKEY或者转了一圈重新回到起点则没找到
    55     }
    56 
    57     return addr;
    58 }
    59 int main()
    60 {
    61     int a[] = {14,1,68,27,55,19,20,84,79,23,11,10};
    62     HashTable h;
    63     initHashTable(h);
    64     for (int i = 0;i<12;i++ )
    65         insertHashTable(h,a[i]);
    66     for (int i=0;i<12;i++)
    67     {
    68         int addr = searchHashTable(h,a[i]);
    69         cout << a[i] << " : " << addr << endl;
    70     }
    71 
    72 
    73     return 0;
    74 }

    排序

    分类:
    1 插入类
    - 直接插入
    - 折半插入
    - 希尔排序
    2 交换类
    - 冒泡排序
    - 快速排序
    3 选择排序
    - 简单选择排序
    - 堆排序
    4 归并类
    - 归并排序
    5 基数排序

      1 #include <iostream>
      2 #include <string.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <stack>
      6 #define SUCCESS 1
      7 #define UNSUCCESS -1
      8 #define NULLkey = -65519
      9 
     10 
     11 using namespace std;
     12 /*
     13 排序
     14 */
     15 // 直接插入排序:每次都是在一个有序的序列中插入一个新的关键字
     16 void insertSort(int r[],int n) // 待排序关键字存储在1-n的位置
     17 {
     18     /*
     19     时间复杂度:
     20     1 最好情况:仅有外层循环 O(n)
     21     2 最坏情况:n*(n-1)/2 O(n^2)
     22     空间复杂度:
     23     辅助存储空间仅有temp,故为O(1)
     24     */
     25     int temp;
     26     for (int i=1;i<=n;i++)
     27     {
     28         temp = r[i];// 存放待插入关键字
     29         int j = i-1;
     30         while (r[j] > temp && j > 0)
     31         {
     32             r[j+1] = r[j];
     33             j--;
     34         }
     35         r[j+1] = temp;
     36 
     37     }
     38 }
     39 
     40 void binsertSort(int r[],int n)
     41 {
     42     /*
     43     和直接插入排序的区别是:查找插入位置所花的时间大大减小
     44     */
     45     for (int i=1;i<=n;i++) // i = 1 时已经为有序数列
     46     {
     47         r[0] = r[i] ; // r[0] 空余空间中存放当前待插入关键字
     48         int low = 1,high = i-1; // 当前的有序序列为1-i-1;
     49         while (low <= high)
     50         {
     51             int mid = (low + high)/2;
     52             if (r[mid] >= r[0])
     53             {
     54                 high = mid-1;
     55             }
     56             else
     57                 low = mid+1;
     58         }
     59         // 之所以让low = high时再进入循环:比较当前关键字和high/low指向关键字的大小
     60         // 离开循环时low = high+1,low指向位置即为待移动的位置
     61         for (int j=i-1;j>=low;j--)
     62             r[j+1] = r[j];
     63         r[low] = r[0];
     64 
     65     }
     66 }
     67 // 希尔排序
     68 void shellInsert(int r[],int n,int dlta)
     69 {
     70     int j;
     71     for (int i = 1+dlta; i<=n ; i++)
     72     { // 循环 n - 1 - dlta 次 = 子序列的个数
     73         if (r[i] < r[i-dlta])
     74         {
     75             r[0] = r[i];
     76             for (j = i-dlta ; j>0 && r[j] > r[0] ; j = j-dlta )
     77                 r[j+dlta] = r[j];
     78             r[j+dlta] = r[0];
     79         }
     80     }
     81 }
     82 void shellSort(int r[],int dlta[],int n,int t )
     83 {
     84     /*
     85     缩小增量排序:对r[n]进行增量为dlta[t]的排序过程
     86     思想:直接插入排序适合基本有序的序列,希尔排序的每趟排序都会使整个序列变得更加有序,
     87     等整个序列基本有序后,最后进行一趟直接插入排序,效率会更高。
     88     注意:1.希尔排序是不稳定的。
     89     2.增量序列的最后一个值一定取1,增量序列中的值尽量没有除1之外的公因子
     90     */
     91     for (int i = 0;i<t;i++)
     92     {
     93         shellInsert(r,n,dlta[i]);
     94     }
     95 }
     96 void bubbleSort(int r[],int n)
     97 {
     98     /*
     99     外层比较n-1次,内层比较n-i次
    100     时间复杂度:O(N^2)
    101     空间复杂度:O(1)
    102     */
    103     int flag;
    104     for (int i = 1;i<n;i++)
    105     {
    106         flag = true;
    107         for (int j = 1;j<=n-i;j++)
    108         {
    109             if (r[j] > r[j+1])
    110             {
    111                 int temp = r[j];
    112                 r[j] = r[j+1];
    113                 r[j+1] = temp;
    114                 flag = false;
    115             }
    116         }
    117         if (flag) // 没发生交换说明有序
    118             break;
    119     }
    120 }
    121 // 快速排序之合并版
    122 /*
    123 通常,快速排序是同量级O(nlogn)的排序方法中,平均性能最好。
    124 但若初始记录序列按关键字有序或基本有序时,快速排序将退化为起泡排序。
    125 空间复杂度:栈
    126 */
    127 void quickSort(int r[],int low,int high)
    128 {
    129     int i = low,j = high;
    130     if (low < high)
    131     {
    132         while (i<j)
    133         {
    134             r[0] = r[low];//枢纽
    135             while (r[j]>r[0] && i < j)
    136                 j -- ;
    137             if (i < j)
    138             {
    139                 // 此时r[j] < r[0] 交换
    140                 r[i] = r[j];
    141                 i++;
    142             }
    143             while (i < j && r[i] < r[0] )
    144                 i++;
    145             if (i<j)
    146             {
    147                 r[j] = r[i];
    148                 j--;
    149             }
    150         }
    151         r[i] = r[0];// 将枢纽定在最终位置
    152         quickSort(r,low,i-1);
    153         quickSort(r,j+1,high);
    154     }
    155 }
    156 
    157 // 快速排序之分离版
    158 int Partition(int r[],int low,int high)
    159 {
    160     while (low<high)
    161     {
    162         r[0] = r[low];
    163         while (low < high && r[high] > r[0]  )
    164             high -- ;
    165         if (low < high)
    166         {
    167             r[low] = r[high];
    168             low++;
    169         }
    170         while (low<high && r[low] < r[0])
    171             low++;
    172         if (low <high)
    173         {
    174             r[high] = r[low];
    175             high--;
    176         }
    177     }
    178     r[low] = r[0];
    179     return r[0];
    180 }
    181 void qsort(int r[],int low,int high)
    182 {
    183     if (low < high)
    184     {
    185         int flag = Partition(r,low,high); // 一分为二并得到枢纽
    186         qsort(r,low,flag -1);
    187         qsort(r,flag+1,high);
    188     }
    189 }
    190 void print(int r[],int n)
    191 {
    192     for (int i=1;i<=n;i++)
    193         cout << r[i] <<' ';
    194     cout << endl;
    195 }
    196 // 简单选择排序
    197 void selectSort(int r[],int n)
    198 {
    199     int i,j,k;
    200     for (i=1;i<=n-1;i++)
    201     {
    202         k = i;
    203         for (j=i;j<=n;j++)
    204         {
    205             if (r[j]<r[k])
    206             {
    207                 k = j;
    208             }
    209         }
    210         if (k!=i)
    211         {
    212             r[0] = r[i];
    213             r[i] = r[k];
    214             r[k] = r[0];
    215         }
    216     }
    217 }
    218 /*
    219 堆排序:定义:非叶子结点的值都不大于(或不小于)其左右孩子结点的值。
    220 将无序序列调整为完全二叉树形式的堆,根节点为最大值或最小值。
    221 通过堆找到最大最小值后放在队列的尾部,将无序队列调整为有序队列。
    222 
    223 执行过程:
    224 1 层次遍历法建立初始堆,找到第一个非叶子结点,按照从右往左,从下往上的顺序,
    225 依次判断是否满足堆定义(假设为大顶堆,即孩子结点的数值是否都小于根节点)。
    226 如不满足则选择孩子中较大的结点和根节点交换,同时判断下移的根节点的值是否满足定义。
    227 2 将当前无序序列的第一个值和最后一个值交换,有序序列中增加一个值。判断和根节点交换的
    228 新节点是否满足堆定义并进行调整。
    229 
    230 时间复杂度:
    231 */
    232 void shift(int r[],int low,int high)
    233 {
    234     int temp = r[low];
    235     int i = low,j = 2*i;
    236     while (j<=high)
    237     {
    238         if (j<high && r[j] < r[j+1])
    239         {
    240             j = j+1; // 选择I节点的孩子中较大的一个
    241         }
    242         if (temp < r[j])
    243         {
    244             r[i] = r[j];
    245             i = j;
    246             j = j*2;
    247         }
    248         else
    249             break;
    250     }
    251     r[i] = temp;
    252 }
    253 void heapSort(int r[],int n)
    254 {
    255     // 1. 找到最后一个非终端节点,从右向左,从下向上进行调整,建立初始堆
    256     int i;
    257     for (i = n/2; i >=1 ;i--)
    258     {
    259         shift(r,i,n);
    260     }
    261     // 2. 将一次调整后的最大值和无序序列的最后一个值交换
    262     for (i = n;i>=2;i--) // 进行n-1次排序
    263     {
    264         r[0] = r[1];
    265         r[1] = r[i];// r[i]为最后一个
    266         r[i] = r[0];
    267         shift(r,1,i-1);//在减小了一个关键字的无序序列中进行调整
    268     }
    269 
    270 }
    271 int main()
    272 {
    273     int n ;
    274     cin >> n;
    275     int r[n];
    276     for (int i=1;i<=n;i++)
    277         cin >>r[i];
    278     //insertSort(r,n);
    279     //binsertSort(r,n);
    280 //    bubbleSort(r,n);
    281     //quickSort(r,1,n);
    282 //    selectSort(r,n);
    283 heapSort(r,n);
    284     print(r,n);
    285 
    286 
    287 
    288 
    289     return 0;
    290 }
  • 相关阅读:
    读《大道至简》第一章有感
    jdk和jre的区别
    题解 LA2911
    题解 UVa11461
    题解 UVa10791
    题解 UVa11489
    题解 LA2889
    题解 UVa11609
    题解 UVa11076
    题解 UVa11752
  • 原文地址:https://www.cnblogs.com/twomeng/p/9509512.html
Copyright © 2020-2023  润新知