//实现哈希表的相关运算算法。 #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 定义最大哈希表长度 #define NULL_KEY -1 // 定义空关键字值 #define DEL_KEY -2 // 定义被删关键字值 typedef int key_type; // 关键字类型 typedef char info_type; // 其他数据类型 typedef struct { key_type key; // 关键字域 info_type data; // 其他数据域 int det_times; // 探测次数域 }HashTable; // 哈希表元素类型 //将关键字插入到哈希表中 void insert_ht(HashTable ha[], int& n, int m, int p, key_type key) { int i; int adr; adr = key % p; if (ha[adr].key == NULL_KEY || ha[adr].key == DEL_KEY) // x[i]可以直接放在哈希表中 { ha[adr].key = key; ha[adr].det_times = 1; } else // 发生冲突时采用线性探测法解决冲突 { i = 1; // i记录x[i]发生冲突的次数 do { adr = (adr + 1) % m; i++; } while (ha[adr].key != NULL_KEY && ha[adr].key != DEL_KEY); ha[adr].key = key; ha[adr].det_times = i; } n++; } //创建哈希表/ void create_ht(HashTable ha[], key_type x[], int n, int m, int p) { int i; int n1 = 0; for (i = 0; i < m; i++) // 哈希表置初值 { ha[i].key = NULL_KEY; ha[i].det_times = 0; } for (i = 0; i < n; i++) insert_ht(ha, n1, m, p, x[i]); } //输出哈希表 void disp_ht(HashTable ha[], int n, int m) { int i; float avg = 0; printf(" 哈希表地址: "); for (i = 0; i < m; i++) { printf("%-4d", i); } printf("\n"); printf(" 哈希表关键字:"); for (i = 0; i < m; i++) { if (ha[i].key == NULL_KEY || ha[i].key == DEL_KEY) { printf(" "); } else { printf("% -4d", ha[i].key); } } printf("\n"); printf(" 探测次数: "); for (i = 0; i < m; i++) { if (ha[i].key == NULL_KEY || ha[i].key == DEL_KEY) { printf(" "); } else { printf("% -4d", ha[i].det_times); } } printf("\n"); for (i = 0; i < m; i++) { if (ha[i].key != NULL_KEY || ha[i].key != DEL_KEY) { avg = avg + ha[i].det_times; } } avg = avg / n; printf(" 平均查找长度ASL(%d)=%g\n", n, avg); } //在哈希表中查找关键字 int search_ht(HashTable ha[], int m, int p, key_type key) { int adr; adr = key % p; while (ha[adr].key != NULL_KEY && ha[adr].key != key) { adr = (adr + 1) % m; // 采用线性探测法找下一个地址 } if (ha[adr].key == key) // 查找成功 return adr; else // 查找失败 return -1; } //删除哈希表中的关键字 int delete_ht(HashTable ha[], int m, int p, int& n, int key) { int adr; adr = search_ht(ha, m, p, key); if (adr != -1) // 在哈希表中找到该关键字 { ha[adr].key = DEL_KEY; n--; // 哈希表长度减1 } else // 在哈希表中未找到该关键字 return 0; } int main(int argc, char* argv[]) { int n,m,p,key,j; int* num; printf("请输入哈希表长度:"); scanf_s("%d", &n); num = (int*)malloc(n * sizeof(int)); printf("请输入关键字:"); for (j = 0; j < n; j++) { scanf_s("%d", &num[j]); } printf("请输入哈希函数的对应除数:"); scanf_s("%d", &p); m = p; int i; HashTable ha[MAX_SIZE]; printf("(1)创建哈希表\n"); create_ht(ha, num, n, m, p); printf("(2)输出哈希表:\n"); disp_ht(ha, n, m); printf("请输入要查找的关键字:"); scanf_s("%d", &key); printf("(3)查找关键字为%d的记录位置\n", key); i = search_ht(ha, m, p, key); if (i != -1) printf(" ha[%d].key=%d\n", i, key); else printf(" 提示:未找到%d\n", key); printf("请输入要删除的关键字"); scanf_s("%d", &key); printf("(4)删除关键字%d\n", key); delete_ht(ha, m, p, n, key); printf("(5)删除后的哈希表:\n"); disp_ht(ha, n, m); printf("(6)查找关键字为%d的记录位置\n", key); i = search_ht(ha, m, p, key); if (i != -1) printf(" ha[%d].key=%d\n", i, key); else printf(" 提示:未找到%d\n", key); printf("(7)插入关键字%d\n", key); insert_ht(ha, n, m, p, key); printf("(8)插入后的哈希表:\n"); disp_ht(ha, n, m); return 0; }
/统计一个字符串中出现的字符及其次数 #include <stdio.h> #include <string.h> #include <malloc.h> #define MAX_WORD (100) typedef struct tnode { char ch; // 字符 int cnt; // 出现次数 struct tnode* lchild; // 左指针 struct tnode* rchild; // 右指针 }BSTNode; // 结点类型 //采用递归方式向二叉排序树中插入一个字符 static void create_bst(BSTNode*& bt, char ch) // 指针的引用 { if (bt == NULL) // bt为空,则建立一个新结点 { bt = (BSTNode*)malloc(sizeof(BSTNode)); bt->ch = ch; bt->cnt = 1; bt->lchild = bt->rchild = NULL; } else if (ch == bt->ch) bt->cnt++; else if (ch < bt->ch) create_bst(bt->lchild, ch); else create_bst(bt->rchild, ch); } //中序遍历二叉排序树 static void inorder(BSTNode* bt) { if (bt != NULL) { inorder(bt->lchild); // 中序遍历左子树 printf(" %c(%d)\n", bt->ch, bt->cnt); // 访问根结点 inorder(bt->rchild); // 中序遍历右子树 } } //销毁二叉排序树 static void destroy_bst(BSTNode* bt) { if (bt != NULL) { destroy_bst(bt->lchild); destroy_bst(bt->rchild); free(bt); } } int main(int argc, char* argv[]) { BSTNode* bt = NULL; int i = 0; char str[MAX_WORD]; printf("输入字符串:"); gets_s(str); while (str[i] != '\0') { create_bst(bt, str[i]); i++; } printf("字符及出现次数:\n"); inorder(bt); printf("\n"); destroy_bst(bt); return 0; }
//判断一个序列是否是二叉排序中的一个合法的查找序列 #include <stdio.h> #include <stdbool.h> #include <malloc.h> #define MAX_SIZE 100 typedef int key_type; // 定义关键字类型 typedef char info_type; typedef struct node { // 记录类型 key_type key; // 关键字项 info_type data; // 其他数据域 struct node* lchild; // 左孩子指针 struct node* rchild; // 右孩子指针 }BSTNode; //以括号表示法输出二叉排序树 void disp_bst(BSTNode* bt); // 函数声明 bool insert_bst(BSTNode*& bt, key_type key) // 在以bt为根结点的BST中插入一个关键字为key的结点 { if (bt == NULL) // 原树为空,新插入的记录为根结点 { bt = (BSTNode*)malloc(sizeof(BSTNode)); bt->key = key; bt->lchild = bt->rchild = NULL; return true; } else if (key == bt->key) return false; else if (key < bt->key) return insert_bst(bt->lchild, key); // 插入到bt结点的左子树中 else return insert_bst(bt->rchild, key); // 插入到bt结点的右子树中 } //建立一颗二叉排序树 BSTNode* create_bst(key_type a[], int n) { BSTNode* bt = NULL; // 初始时bt为空树 int i = 0; while (i < n) { if (insert_bst(bt, a[i]) == 1) // 将a[i]插入二叉排序树bst中 { printf(" 第%d步,插入%d:", i + 1, a[i]); disp_bst(bt); printf("\n"); i++; } } return bt; } //以括号表示法输出二叉排序树 void disp_bst(BSTNode* bt) { if (bt != NULL) { printf("%d", bt->key); if (bt->lchild != NULL || bt->rchild != NULL) { printf("("); // 有孩子结点时才输出( disp_bst(bt->lchild); // 递归处理左子树 if (bt->rchild != NULL) printf(","); // 有右孩子结点时才输出, disp_bst(bt->rchild); // 递归处理右子树 printf(")"); // 有孩子结点时才输出) } } } key_type predt = -32767; // predt为全局变量,保存当前结点中序前驱的值,初值为-∞//判断bt是否为BST bool judge_bst(BSTNode* bt) { bool b1, b2; if (bt == NULL) return true; else { b1 = judge_bst(bt->lchild); if (b1 == false || predt >= bt->key) return false; b2 = judge_bst(bt->rchild); return b2; } } //销毁一颗BST void destroy_bst(BSTNode* bt) { if (bt != NULL) { destroy_bst(bt->lchild); destroy_bst(bt->rchild); free(bt); } } //判断a是否为bt中的一个合法查找序列 static bool find_seq(BSTNode* bt, int a[], int n) { int i = 0; BSTNode* p = bt; while (i < n && p != NULL) { if (i == n - 1 && a[i] == p->key) // a查找完毕,返回true return true; if (p->key != a[i]) // 若不等,表示a不是查找序列,返回false return false; i++; // 查找序列指向下一个关键字 if (a[i] < p->key) p = p->lchild; // 在左子树中查找 else if (a[i] > p->key) p = p->rchild; // 在右子树中查找 } return false; } int main(int argc, char* argv[]) { BSTNode* bt; int m, n; int* num, * num1; printf("请输入数组长度:"); scanf_s("%d", &m); num = (int*)malloc(m * sizeof(int)); printf("请输入数组:"); for (int j = 0; j < m;j++) { scanf_s("%d", &num[j]); } printf("(1)构造二叉排序树bt\n"); bt = create_bst(num, m); // 创建二叉排序树 printf("(2)输出BST:"); disp_bst(bt); // 5(2(1,3(,4)),6(,8(7,9))) printf("\n"); printf("请输入要判断序列的长度:"); scanf_s("%d", &m); printf("请输入要判断的序列:"); num1 = (int*)malloc(m * sizeof(int)); for (int j = 0; j < m; j++) { scanf_s("%d", &num1[j]); } if (find_seq(bt, num1, m)) printf("是一个查找序列\n"); else printf("不是一个查找序列\n"); printf("请输入要判断序列的长度:"); scanf_s("%d", &m); printf("请输入要判断的序列:"); num1 = (int*)malloc(m * sizeof(int)); for (int j = 0; j < m; j++) { scanf_s("%d", &num1[j]); } if (find_seq(bt, num1, m)) printf("是一个查找序列\n"); else printf("不是一个查找序列\n"); printf("(4)销毁bt\n"); destroy_bst(bt); return 0; }
#include <stdio.h> #include<stdlib.h> #define MAXSZIE 100 typedef int KeyType; typedef struct { KeyType key; // 关键字项 char data; // 其他数据项 }RedType; // 查找元素的类型 //创建顺序表 void CreateList(RedType L[], KeyType dk[], int n) { int i; for (i = 0; i < n; i++) L[i].key = dk[i]; } //输出顺序表 void Display(RedType L[], int n) { int i; for (i = 0; i < n; i++) printf("%d ", L[i].key); printf("\n"); } //x和y交换 void swap(RedType& n, RedType& m) { RedType a = n; n = m; m = a; } //---------直接插入排序,按递增有序进行 static void InsertSort(RedType A[], int n) { int i, j; RedType tmp; for (i = 1; i < n; i++) { printf("插入%d, 排序后: ",A[i].key); if (A[i].key < A[i - 1].key) // 反序时 { tmp = A[i]; j = i - 1; do // 找recs[i]的插入位置 { A[j + 1] = A[j]; // 将关键字大于recs[i].key的记录后移 j--; } while (j >= 0 && A[j].key > tmp.key); A[j + 1] = tmp; // 在j + 1处插入recs[i] } Display(A, n); } } //按递增有序进行折半插入排序 static void BInsertSort(RedType L[], int n) { int i; int j; int low; int high; int mid; RedType tmp; for (i = 1; i < n; i++) { if (L[i].key < L[i - 1].key) // 反序时 { printf(" 插入%d, 排序后: ",L[i].key); tmp = L[i]; // 将recs[i]保存到tmp中 low = 0; high = i - 1; while (low <= high) { mid = (low + high) / 2; // 取中间位置 if (tmp.key < L[mid].key) high = mid - 1; // 插入点在左半区 else low = mid + 1; // 插入点在右半区 } for (j = i - 1; j >= high + 1; j--) // 集中进行元素后移 L[j + 1] = L[j]; L[high + 1] = tmp; // 插入tmp } Display(L, n); } } //按递增有序进行希尔排序 static void ShellSort(RedType L[], int n) { int i; int j; int d; RedType tmp; d = n / 2; // 增量置初值 while (d > 0) { for (i = d; i < n; i++) // 对所有组采用直接插入排序 d = 5, 2, 1 { tmp = L[i]; // 对相隔d个位置一组采用直接插入排序 j = i - d; while (j >= 0 && tmp.key < L[j].key) { L[j + d] = L[j]; j = j - d; } L[j + d] = tmp; } printf(" d = %d: ", d); Display(L, n); d = d / 2; // 减小增量 } } //二路归并排序 // 将两个有序表归并为一个有序表 int cnt = 1;// 全局变量 static void merge_recs(RedType L[], int low, int mid, int high) { RedType* rec1; int i = low; int j = mid + 1; int k = 0; // k是rec1的下标,i,j分别为第1、2段的下标 rec1 = (RedType*)malloc((high - low + 1) * sizeof(RedType)); // 动态分配空间 while (i <= mid && j <= high) { if (L[i].key <= L[j].key) // 将第1段中的记录放入rec1中 { rec1[k] = L[i]; i++; k++; } else // 将第2段中的记录放入rec1中 { rec1[k] = L[j]; j++; k++; } } while (i <= mid) // 将第1段余下部分复制到rec1 { rec1[k] = L[i]; i++; k++; } while (j <= high) // 将第2段余下部分复制到rec1 { rec1[k] = L[j]; j++; k++; } for (k = 0, i = low; i <= high; k++, i++) // 将rec1复制回recs中 L[i] = rec1[k]; } //实现有序表长度为len的一趟归并 static void merge_pass(RedType L[], int len, int n) { int i; printf("第%d趟归并:", cnt++); for (i = 0; i + 2 * len - 1 < n; i = i + 2 * len) // 归并len长的两相邻子表 { merge_recs(L, i, i + len - 1, i + 2 * len - 1); } if (i + len - 1 < n - 1) // 余下两个子表,后者长度小于len { merge_recs(L, i, i + len - 1, n - 1); // 归并这两个子表 } Display(L, n); // 输出该趟的排序结果 } //二路归并排序 static void MergeSort(RedType L[], int n) { int len; for (len = 1; len < n; len = 2 * len) // len = 1, 2, 4, 8 merge_pass(L, len, n); } //堆排序 //创建顺序表 void CreateList1(RedType L[], KeyType dk[], int n) { int i; for (i = 1; i <= n; i++) // L[1...n]存放排序记录 { L[i].key = dk[i - 1]; } } //输出顺序表 void Display1(RedType L[], int n) { int i; for (i = 1; i <= n; i++) { printf("%d ", L[i].key); } printf("\n"); } int cnt1 = 1; // 全局变量,累计排序趟数 //以括号表示法输出建立的堆 static void disp_heap(RedType L[], int i, int n) { if (i <= n) printf("%d", L[i].key); // 输出根结点 if (2 * i <= n || 2 * i + 1 < n) { printf("("); if (2 * i <= n) disp_heap(L, 2 * i, n); // 递归调用输出左子树 printf(","); if (2 * i + 1 <= n) disp_heap(L, 2 * i + 1, n); // 递归调用输出右子树 printf(")"); } } //堆筛选算法 static void sift(RedType L[], int low, int high) { int i = low; // L[j]是recs[i]的左孩子 int j = 2 * i; RedType temp = L[i]; while (j <= high) { if (j < high && L[j].key < L[j + 1].key) // 若右孩子较大,把j指向右孩子 j++; // 变为2i+1 if (temp.key < L[j].key) { L[i] = L[j]; // 将recs[j]调整到双亲结点位置上 i = j; // 修改i和j值,以便继续向下筛选 j = 2 * i; } else break; // 筛选结束 } L[i] = temp; // 被筛选结点的值放入最终位置 } //堆排序 static void HeapSort(RedType L[], int n) { int i, j; for (i = n / 2; i >= 1; i--) // 循环建立初始堆 sift(L, i, n); printf("初始堆:"); disp_heap(L, 1, n); // 输出初始堆9(8(6(2,4),5(0,)),7(1,3)) printf("\n"); for (i = n; i >= 2; i--) // 进行n-1次循环,完成堆排序 { printf("第%d趟排序:", cnt1++); swap(L[1], L[i]); // 将第一个元素同当前区间内的recs[1]对换 printf(" 排序结果:"); // 输出每一趟的排序结果 for (j = 1; j <= n; j++) printf("%2d ", L[j].key); sift(L, 1, i - 1); // 筛选recs[1]结点,得到i-1个结点的堆 printf("\n"); } } //按递增有序进行简单选择排序 static void SelectSort(RedType L[], int n) { int i, j, k; for (i = 0; i < n - 1; i++) // 做第i趟排序 { k = i; // k从0~8 for (j = i + 1; j < n; j++) // 在当前无序区recs[i..n-1]中选key最小的recs[k] j从1~9 { if (L[j].key < L[k].key) { k = j; // k记下目前找到的最小关键字所在的位置 } } if (k != i) { swap(L[i], L[k]); // 交换recs[i]和recs[k] } printf(" i = %d, 排序结果:", i); Display(L, n); // 输出每一趟的排序结果 } } //快速排序 //显示一趟划分后的结果 static void disp_partition(RedType L[], int s, int t) { static int i = 1; // 局部静态变量仅被初始化一次 int j; printf("第%d次划分:", i); for (j = 0; j < s; j++) printf(" "); for (j = s; j <= t; j++) printf("%3d", L[j].key); printf("\n"); i++; } //一趟划分 static int partition_recs(RedType L[], int s, int t) { int i = s, j = t; RedType tmp = L[i]; // 以recs[i]为基准 [6, 8, 7, 9, 0, 1, 3, 2, 4, 5] while (i < j) // 从两端交替向中间扫描,直至i=j为止 { while (i < j && L[j].key >= tmp.key) j--; // 从右向左扫描,找一个小于tmp.key的recs[j] L[i] = L[j]; // 找到这样的recs[j],放入recs[i]处 while (i < j && L[i].key <= tmp.key) i++; // 从左向右扫描,找一个大于tmp.key的recs[i] L[j] = L[i]; // 找到这样的recs[i],放入recs[j]处 } L[i] = tmp; disp_partition(L, s, t); return i; } //递增快速排序 static void QuickSort(RedType L[], int s, int t) { int i; if (s < t) // 区间内至少存在两个元素的情况 { i = partition_recs(L, s, t); QuickSort(L, s, i - 1); // 对左区间递归排序 QuickSort(L, i + 1, t); // 对右区间递归排序 } } //冒泡排序按递增有序进行 static void BubbleSort(RedType L[], int n) { int i; int j; bool exchange; for (i = 0; i < n - 1; i++) // 循环趟数 { exchange = false; // 一趟前exchange置为假 for (j = n - 1; j > i; j--) // 归位recs[i],循环n-i-1次 { if (L[j].key < L[j - 1].key) // 相邻两个元素反序时 { swap(L[j], L[j - 1]); // 将这两个元素交换 exchange = true; // 一旦有交换,exchange置为真 } } printf("第%d次,排序结果: ", i, L[i].key); Display(L, n); if (!exchange) // 本趟没有发生交换,中途结束算法 return; } } int main() { int n = 10; KeyType a[] = { 8,7,56,48,23,3,4,6,1,15 }; RedType L[MAXSZIE]; //直接插入排序 printf("-------------直接插入排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); InsertSort(L, n); printf("总排序后: "); Display(L, n); printf("\n"); //折半插入排序 printf("-------------折半插入排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); BInsertSort(L, n); printf("排序后: "); Display(L, n); printf("\n"); //希尔排序 printf("-------------希尔排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); ShellSort(L, n); printf("排序后: "); Display(L, n); printf("\n"); //二路归并排序 printf("-------------二路归并排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); MergeSort(L, n); printf("排序后: "); Display(L, n); printf("\n"); //堆排序 printf("-------------堆排序\n"); CreateList1(L, a, n); printf("排序前: "); Display1(L, n); HeapSort(L, n); printf("排序后: "); Display1(L, n); printf("\n"); //简单选择排序 printf("-------------简单选择排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); SelectSort(L, n); printf("排序后: "); Display(L, n); printf("\n"); //快速排序 printf("-------------快速排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); QuickSort(L, 0, n - 1);// 0 9 printf("排序后: "); Display(L, n); printf("\n"); //冒泡排序 printf("-------------冒泡排序\n"); CreateList(L, a, n); printf("排序前: "); Display(L, n); BubbleSort(L, n); printf("排序后: "); Display(L, n); return 0; }
#include <stdio.h> #include <malloc.h> #include <string.h> #include<string.h> #define MAXSIZE 9 // 单词的最大长度 #define RADIX 27 typedef char String[MAXSIZE + 1]; // 定义String为字符数组类型 typedef struct node { String word; struct node* next; }LinkNode; // 单链表结点类型 //输出单词 static void Display(String R[], int n) { int i; for (i = 0; i < n; i++) { printf("%s ", R[i]); } printf("\n"); } //对单词进行预处理 static void ProProcess(String R[], int n) { int i, j; for (i = 0; i < n; i++) { if (strlen(R[i]) < MAXSIZE) { for (j = strlen(R[i]); j < MAXSIZE; j++) { R[i][j] = ' '; } R[i][j] = '\0'; } } } //恢复处理 static void EndProcess(String R[], int n) { int i, j; for (i = 0; i < n; i++) { for (j = MAXSIZE - 1; R[i][j] == ' '; j--) R[i][j + 1] = '\0'; } } //根据关键字的第分量进行分配 static void Distribute(String R[], LinkNode* head[], LinkNode* tail[], int j, int n) { int i; // 循环变量 int k; // 队列编号 LinkNode* p; for (i = 0; i < n; i++) // 依次扫描R[i],将其入队 { if (R[i][j] == ' ') // 空格时放入0号队列中,'a'放入1号队列中,...... k = 0; else k = R[i][j] - 'a' + 1; p = (LinkNode*)malloc(sizeof(LinkNode)); // 创建新结点 strcpy_s(p->word, R[i]); p->next = NULL; if (head[k] == NULL) { head[k] = p; tail[k] = p; } else { tail[k]->next = p; tail[k] = p; } } } //收集结点 static void Collect(String R[], LinkNode* head[]) { int i; int k = 0; LinkNode* pre, * p; for (i = 0; i < RADIX; i++) { if (head[i] != NULL) { pre = head[i]; p = pre->next; while (p != NULL) { strcpy_s(R[k++], pre->word); free(pre); pre = p; p = p->next; } strcpy_s(R[k++], pre->word); free(pre); } } } //进行基数排序 static void RadixSort(String R[], int n) { int i, j; LinkNode* head[RADIX], * tail[RADIX]; for (i = MAXSIZE - 1; i >= 0; i--) // 从低位到高位做MAX_LEN趟基数排序 { for (j = 0; j < RADIX; j++) head[j] = tail[j] = NULL; Distribute(R, head, tail, i, n); // 第i趟分配 Collect(R, head); // 第i趟收集 } } int main(void) { int n = 7; String W[] = {"abandon", "apple", "except", "you", "edg", "cat","math"}; printf("排序前:\n"); Display(W, n); ProProcess(W, n); printf("预处理后:\n"); Display(W, n); RadixSort(W, n); printf("排序结果:\n"); Display(W, n); EndProcess(W, n); printf("最终结果:\n"); Display(W, n); return 0; }
标签:排序,int,代码,bt,查找,key,printf,ha From: https://www.cnblogs.com/cyfan/p/16974159.html