diff --git "a/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/ds homework9 sort.c" "b/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/ds homework9 sort.c" new file mode 100644 index 00000000..fbe45d1d --- /dev/null +++ "b/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/ds homework9 sort.c" @@ -0,0 +1,332 @@ +//实现第九次作业 各种排序(必选+归并排序) 其中插入排序、希尔排序、冒泡排序、简单选择排序均未改变原测试数组顺序 +//在快速排序和归并排序中使用了递归,直接对原测试数组进行了排序 +#include +#include +#include + +void Print(int *t, int len,int c,int m); +void swap(int *a, int *b); +int c = 0; +int m = 0;//记录排序的比较与移动次数 + +//copy函数 +int * Copy(int s[],int len) +{ + int *r;//copy原数组 + r = (int *)malloc(len * sizeof(int)); + for (int m = 0; m < len; m++) + r[m] = s[m]; + return r; +} + +//直接插入排序 +void InsertSort(int s[], int len) +{ + int insertVal = 0; + int i = 0, j = 0; + c = 0; + m = 0; + for (i = 1; i < len; ++i) + { + insertVal = s[i]; + //若第i-1个元素大于第i个元素,则移动后插入; + //否则无需任何操作 + if (s[i - 1] > insertVal) + { + j = i - 1; + //寻找插入位置,一边寻找一边后移 + while (j >= 0 && s[j] > insertVal) + { + s[j + 1] = s[j]; + --j; + c++; + } + s[j + 1] = insertVal; + m++; + } + + } + +} + +//希尔排序 +void ShellSort(int s[], int len) +{ + int i, j, k; + c = 0; + m = 0; + int gap; //gap是分组的长度 + int temp; //因为希尔排序是在直接插入排序的基础上实现的,所以仍然需要监视哨 + for (gap = len / 2; gap>0; gap = gap / 2) + { + for (i = 0; i= 0 && s[k]>temp) + { + s[k + gap] = s[k]; + k = k - gap; + } + s[k + gap] = temp; + + } + c++; + }m++; + } + } +} + + +//冒泡排序 +void BubbleSort(int s[], int len) +{ + int i, j,t; + c = 0; + m = 0; + for (i = 0; i < len; i++) + { + for (j = i + 1; j < len; j++) + { + if (s[i] > s[j]) + { + swap(&s[i], &s[j]); + } + c++; + } + m++; + } +} + +//交换 +void swap(int *a, int *b) +{ + int temp; + + temp = *a; + *a = *b; + *b = temp; + + return; +} + +//简单选择排序 +void SelectSort(int s[], int len)//n为数组a的元素个数 +{ + c = 0; + m = 0; + //进行N-1轮选择 + for (int i = 1 - 1; i= i; j--) + { + if (s[j] < s[min]) + { + min = j; + } + m++; + } + //将第i小的数,放在第i个位置;如果刚好,就不用交换 + if (i != min) + { + swap(&s[i], &s[min]); + } + c++; + } +} + +//快速排序 +void QuickSort(int s[], int len, int low, int high) +{ + int i, j; + if (low < high) + { + i = low + 1; // 将s[low]作为基准数,因此从s[low+1]开始与基准数比较! + j = high; // s[high]是数组的最后一位 + + while (i < j) + { + if (s[i] > s[low]) // 如果比较的数组元素大于基准数,则交换位置。 + { + swap(&s[i], &s[j]); // 交换两个数 + j--; + c++; + } + else + { + i++; // 将数组向后移一位,继续与基准数比较。 + m++; + } + + } + + /* 跳出while循环后,i = j。 + * 此时数组被分割成两个部分 --> s[low+1] ~ s[i-1] < s[low] + * --> s[i+1] ~ s[high] > s[low] + * 这个时候将数组s分成两个部分,再将s[i]与s[low]进行比较,决定s[i]的位置。 + * 最后将s[i]与s[low]交换,进行两个分割部分的排序!以此类推,直到最后i = j不满足条件就退出! + */ + + if (s[i] >= s[low]) // 这里必须要取等“>=”,否则数组元素由相同的值时,会出现错误! + { + i--; + m++; + } + + swap(&s[low], &s[i]); // 交换s[i]与s[low] + + QuickSort(s, len, low, i); + QuickSort(s, len, j, high); + } +} + +//归并排序 +void merge(int s[], int low, int mid, int high) +{ + int i, k; + int *tmp = (int *)malloc((high - low + 1) * sizeof(int)); + //申请空间,使其大小为两个 + int left_low = low; + int left_high = mid; + int right_low = mid + 1; + int right_high = high; + for (k = 0; left_low <= left_high && right_low <= right_high; k++) + { // 比较两个指针所指向的元素 + if (s[left_low] <= s[right_low]) + { + tmp[k] = s[left_low++]; + m++; + } + else + { + tmp[k] = s[right_low++]; + m++; + } + c++; + } + if (left_low <= left_high) + { + + for (i = left_low; i <= left_high; i++) + { + tmp[k++] = s[i]; + m++; + } + } + if (right_low <= right_high) + { + + for (i = right_low; i <= right_high; i++) + { + tmp[k++] = s[i]; + m++; + } + } + for (i = 0; i < high - low + 1; i++) + { + s[low + i] = tmp[i]; + m++; + } + free(tmp); + return; +} + +void MergeSort(int s[], int first, int last) +{ + int mid = 0; + if (first> 1); + MergeSort(s, first, mid); + MergeSort(s, mid + 1, last); + merge(s, first, mid, last); + } + return; +} + +void Print(int *t,int len,int c,int m) +{ + + for (int j = 0; j < len; j++) + printf("%d ", t[j]); + printf("care: %d m: %d total: %d\n", c, m, c + m); + +} + +int main() +{ + int n; + srand((int)time(NULL)); /*定义这个可以产生不同的随机数*/ + n = rand() %5+10; + printf("%d\n", n); + int *t; + t = (int *)malloc(n*sizeof(int)); + for (int i = 0; i < n; i++) + { + t[i] = rand() % 200; + } + + //copy测试数组 + int *a,*b,*d,*e,*h; + a = Copy(t,n); + b = Copy(t, n); + e = Copy(t, n); + d = Copy(t, n); + h = Copy(t, n); + + printf("Example: "); + for (int j = 0; j < n; j++) + printf("%d ", t[j]); + printf("\n\n"); + + //直接插入排序 + printf("InsertSort: "); + InsertSort(a, n); + Print(a, n, c, m); + + //希尔排序 + printf("ShellSort: "); + ShellSort(b, n); + Print(b, n, c, m); + + //冒泡排序 + printf("BubbleSort: "); + BubbleSort(d, n); + Print(d, n, c, m); + + + //简单选择排序 + printf("SelectSort: "); + SelectSort(e, n); + Print(e, n, c, m); + + //快速排序 + c = 0; + m = 0; + printf("QuickSort: "); + QuickSort(h,n,0,n-1); + Print(h, n, c, m); + + //归并排序 + c = 0; + m = 0; + printf("MergeSort: "); + MergeSort(t, 0, n - 1); + Print(t, n, c, m); + + free(t); + free(a); + free(b); + free(d); + free(e); + free(h); + return 0; +} \ No newline at end of file diff --git "a/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/test1.PNG" "b/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/test1.PNG" new file mode 100644 index 00000000..4ed517a7 Binary files /dev/null and "b/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/test1.PNG" differ diff --git "a/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/test2.PNG" "b/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/test2.PNG" new file mode 100644 index 00000000..17125459 Binary files /dev/null and "b/2017-1/LLF/\347\254\254\344\271\235\346\254\241\344\275\234\344\270\232-\345\256\236\347\216\260\345\220\204\347\247\215\346\216\222\345\272\217/test2.PNG" differ diff --git "a/2017-1/LLF/\347\254\254\345\215\201\346\254\241\344\275\234\344\270\232-\345\223\210\345\270\214\350\241\250/hash.c" "b/2017-1/LLF/\347\254\254\345\215\201\346\254\241\344\275\234\344\270\232-\345\223\210\345\270\214\350\241\250/hash.c" new file mode 100644 index 00000000..1755bf3b --- /dev/null +++ "b/2017-1/LLF/\347\254\254\345\215\201\346\254\241\344\275\234\344\270\232-\345\223\210\345\270\214\350\241\250/hash.c" @@ -0,0 +1,244 @@ +//Hash查找表的建立、关键字查找和重建哈希表(扩充原Hash表容量)操作实现 +//使用“开放定址法之线性探测再散列”解决Hash冲突 (随机数据插入) +#include +#include +#include +#include +#define NULLKEY 0 // 0为无记录标志 +#define N 10 // 数据元素个数 +#define SIZE 6 +#define SUCCESS 1 +#define UNSUCCESS 0 +#define DUPLICATE -1 +typedef int KeyType;// 设关键字域为整型 + + // 开放定址哈希表的存储结构 +typedef struct +{ + KeyType key;//关键字 + int val;//值 +}ElemType; // 数据元素类型 + +int hashsize[] = { 11,19,29,37 }; // 哈希表容量递增表,一个合适的素数序列 +int m = 0; // 哈希表表长,全局变量 + + //定义哈希表 +typedef struct +{ + ElemType *elem; // 数据元素存储基址,动态分配数组 + int count; // 当前数据元素个数 + int sizeindex; // hashsize[sizeindex]为当前容量 +}HashTable; + +// 构造一个空的哈希表 +int InitHashTable(HashTable *H) +{ + int i; + (*H).count = 0; // 当前元素个数为0 + (*H).sizeindex = 0; // 初始存储容量为hashsize[0] + m = hashsize[0]; + (*H).elem = (ElemType*)malloc(m * sizeof(ElemType)); + if (!(*H).elem) + exit(0); // 存储分配失败 + for (i = 0; i < m; i++) + { + (*H).elem[i].key = NULLKEY; // 未填记录的标志 + } + return 1; +} + +// 销毁哈希表H +void DestroyHashTable(HashTable *H) +{ + free((*H).elem); + (*H).elem = NULL; + (*H).count = 0; + (*H).sizeindex = 0; +} + +// 一个简单的哈希函数(m为表长,全局变量) +unsigned Hash(KeyType K) +{ + return K%m; +} + +// 开放定址法处理冲突 +void collision(int *p, int d) // 线性探测再散列 +{ + *p = (*p + d) % m; +} + +// 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据 +// 元素在表中位置,并返回SUCCESS;否则,以p指示插入位置,并返回UNSUCCESS +// c用以计冲突次数,其初值置零,供建表插入时参考。 +int SearchHash(HashTable H, KeyType K, int *p, int *c) +{ + *p = Hash(K); // 求得哈希地址 + while (H.elem[*p].key != NULLKEY && !(K == H.elem[*p].key)) + { + // 该位置中填有记录.并且关键字不相等 + (*c)++; + if (*ckey != NULLKEY) // 该单元有数据 + *p++ = *((*H).elem + i); + (*H).count = 0; + (*H).sizeindex++; // 增大存储容量 + m = hashsize[(*H).sizeindex]; + p = (ElemType*)realloc((*H).elem, m * sizeof(ElemType)); + if (!p) + exit(0); // 存储分配失败 + (*H).elem = p; + for (i = 0; i0 }\n", i); + } +} + +// 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据 +// 元素在表中位置,并返回SUCCESS;否则,返回UNSUCCESS +int Find(HashTable H, KeyType K, int *p) +{ + int c = 0; + *p = Hash(K); // 求得哈希地址 + while (H.elem[*p].key != NULLKEY && !(K == H.elem[*p].key)) + { // 该位置中填有记录.并且关键字不相等 + c++; + if (c%d }\n", p, r.key, r.val); +} + +ElemType newElemType(KeyType key, int val) +{ + ElemType temp = { key,val }; + return temp; +} + +ElemType* Inputs(int size) +{ + ElemType* a = (ElemType*)malloc(size * sizeof(ElemType)); + for (int i = 0; i < size; ++i) + { + a[i] = newElemType(rand() % 100, rand() % 100); + } + return a; +} + +int main() +{ + srand(time(0)); + ElemType* r = Inputs(SIZE); + HashTable h; + int i, j, p; + KeyType k=0; + + InitHashTable(&h); + for (i = 0; i