├── .gitignore ├── README.md ├── algorithm └── sort │ ├── main.c │ ├── sort.c │ └── sort.h └── dataStructure ├── bitTree ├── bittree.c ├── bittree.h └── main.c ├── doubleLinkedList ├── dlist.c ├── dlist.h └── main.c ├── hashTable ├── hashtable.c ├── hashtable.h └── main.c ├── linkedList ├── main.c ├── slist.c └── slist.h ├── queue ├── main.c ├── queue.c └── queue.h └── stack ├── main.c ├── stack.c └── stack.h /.gitignore: -------------------------------------------------------------------------------- 1 | #exe 2 | *.exe 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CDataStructure -- c语言的基本数据结构练习 2 | 3 | ### bitTree  二叉搜索树 4 | 5 | ### doubleLinkedList 双链表 6 | 7 | ### linkedList 单链表 8 | 9 | ### queue 队列 10 | 11 | ### stack 栈 12 | 13 | ### algorithm 算法 14 | 15 | #### sort 排序 16 | - 冒泡排序 17 | - 插入排序 18 | - 归并排序 19 | - 快速排序 20 | - 计数排序 21 | - 基数排序 22 | -------------------------------------------------------------------------------- /algorithm/sort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sort.h" 3 | #define LEN 5 4 | int main() 5 | { 6 | int arr[LEN] = {124,342,311,34,295}; 7 | printData(arr, LEN, "original array:"); 8 | //冒泡排序--升序 9 | bubbleSort(arr, LEN); 10 | printData(arr, LEN, "insert sort:"); 11 | //插入排序--降序 12 | insertSort(arr, LEN); 13 | printData(arr, LEN, "insert sort:"); 14 | //归并排序--升序 15 | mergeSort(arr, 0, LEN - 1); 16 | printData(arr, LEN, "merge sort:"); 17 | //快速排序--降序 18 | quickSort(arr, 0, LEN - 1); 19 | printData(arr, LEN, "quick sort:"); 20 | //计数排序法 21 | int out[LEN]; 22 | int maxValue = max(arr, LEN); 23 | countSort(arr, out, LEN, maxValue); 24 | printData(out, LEN, "count sort:"); 25 | //基数排序法 26 | int out[LEN]; 27 | radixSort(arr, out, LEN); 28 | printData(out, LEN, "radix sort:"); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /algorithm/sort/sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sort.h" 3 | 4 | //插入排序--倒序 5 | void insertSort(int arr[], int length) 6 | { 7 | int j, i, tmp; 8 | if(length == 0) { 9 | return; 10 | } 11 | for (i = 1; i < length; i++) 12 | { 13 | tmp = arr[i]; 14 | j = i-1; 15 | while(tmp > arr[j] && j >= 0) 16 | { 17 | arr[j + 1] = arr[j]; 18 | j--; 19 | } 20 | arr[j + 1] = tmp; 21 | } 22 | } 23 | 24 | //打印数组数据 25 | void printData(int *arr, int length, char *s) 26 | { 27 | int i; 28 | printf("\n%s\n", s); 29 | for (i = 0; i < length; ++i) 30 | { 31 | printf("%d ", *(arr+i)); 32 | } 33 | } 34 | 35 | //归并排序--合并数组 36 | void merge(int arr[], int start, int mid, int end) 37 | { 38 | int n1 = (mid - start) + 1; 39 | int n2 = (end - mid); 40 | int arr1[n1], arr2[n2]; 41 | int i,j,n; 42 | for (i = 0; i < n1; ++i) 43 | arr1[i] = arr[start + i]; 44 | for (j = 0; j < n2; ++j) 45 | arr2[j] = arr[j + mid +1]; 46 | i = j = 0; 47 | n = start; 48 | while(i < n1 && j < n2) 49 | { 50 | if(arr1[i] < arr2[j]) 51 | arr[n] = arr1[i++]; 52 | else 53 | arr[n] = arr2[j++]; 54 | n++; 55 | } 56 | while(i < n1) 57 | arr[n++] = arr1[i++]; 58 | while(j < n2) 59 | arr[n++] = arr2[j++]; 60 | } 61 | 62 | /** 63 | * 归并排序法 64 | */ 65 | void mergeSort(int arr[], int start, int end) 66 | { 67 | int mid; 68 | if(start < end) { 69 | mid = (start + end) / 2; 70 | mergeSort(arr, start, mid); 71 | mergeSort(arr, mid+1, end); 72 | merge(arr, start, mid, end); 73 | } 74 | } 75 | 76 | /** 77 | * 快速排序 78 | */ 79 | void quickSort(int arr[], int start, int end) 80 | { 81 | if(start< end) { 82 | int mid; 83 | mid = partition(arr, start, end); 84 | quickSort(arr, start, mid - 1); 85 | quickSort(arr, mid + 1, end); 86 | } 87 | } 88 | 89 | /** 90 | * 快速排序切分 91 | */ 92 | int partition(int arr[], int start, int end) 93 | { 94 | int measure = arr[end]; 95 | int tmp, j, lowNumPointer = start - 1; 96 | for(j = start; j < end; j++) 97 | { 98 | if(arr[j] >= measure) 99 | { 100 | lowNumPointer = lowNumPointer+1; 101 | tmp = arr[j]; 102 | arr[j] = arr[lowNumPointer]; 103 | arr[lowNumPointer] = tmp; 104 | } 105 | } 106 | tmp = arr[end]; 107 | arr[end] = arr[lowNumPointer + 1]; 108 | arr[lowNumPointer + 1] = tmp; 109 | return lowNumPointer + 1; 110 | } 111 | 112 | /** 113 | * 冒泡排序 114 | **/ 115 | void bubbleSort(int arr[], int length) 116 | { 117 | int exchangeFlag = 1, i,j, tmp; 118 | for (i = 0; i < length && exchangeFlag; ++i) 119 | { 120 | exchangeFlag = 0; 121 | for (j = 0; j < length - i - 1; ++j) 122 | { 123 | if(arr[j] > arr[j+1]) { 124 | exchangeFlag = 1; 125 | tmp = arr[j+1]; 126 | arr[j+1] = arr[j]; 127 | arr[j] = tmp; 128 | } 129 | } 130 | } 131 | } 132 | 133 | /** 134 | * 计数排序法 135 | * @param int range 数值的最大值即范围 136 | **/ 137 | void countSort(int arr[], int out[], int length, int range) 138 | { 139 | int tmp[range], i; 140 | //初始化 141 | for (i = 0; i < range + 1; ++i) 142 | tmp[i] = 0; 143 | //计算数值出现的次数 144 | for (i = 0; i < length; ++i) 145 | tmp[arr[i]] = tmp[arr[i]] + 1; 146 | //计算数字的下标 147 | for (i = 1; i < range + 1; ++i){ 148 | tmp[i] = tmp[i] + tmp[i-1]; 149 | } 150 | //排序结果 151 | for(i = length - 1; i > -1; i--) 152 | { 153 | out[tmp[arr[i]] - 1] = arr[i]; //注意tmp[arr[i]] - 1必须-1,因为计算数字的下标的时候出来的是实际数组的下标+1 154 | tmp[arr[i]] = tmp[arr[i]] - 1; 155 | } 156 | } 157 | 158 | //求最大值 159 | int max(int arr[], int length) 160 | { 161 | int max = arr[0], i; 162 | for (i = 1; i < length; ++i) 163 | if(arr[i] > max) max = arr[i]; 164 | return max; 165 | } 166 | 167 | //三位数的十进制基数排序法 168 | void radixSort(int arr[], int output[], int length) 169 | { 170 | int tmp[length], i; 171 | //个位 172 | for(i = 0; i < length; ++i) 173 | tmp[i] = arr[i]%10; 174 | radixCountSort(tmp, output, arr, length, 10); 175 | for(i = 0; i < length; ++i) 176 | arr[i] = output[i]; 177 | //十位 178 | for(i = 0; i < length; ++i) 179 | tmp[i] = output[i]/10 % 10; 180 | radixCountSort(tmp, output, arr, length, 10); 181 | for(i = 0; i < length; ++i) 182 | arr[i] = output[i]; 183 | //百位 184 | for(i = 0; i < length; ++i) 185 | tmp[i] = output[i]/100; 186 | radixCountSort(tmp, output, arr, length, 10); 187 | } 188 | 189 | /** 190 | * 基数排序用到的计数排序法 191 | * @param array arr 要排序的数组 192 | * @param array out 输出 193 | * @param array origin 原始数组 194 | * @param array length 数组长度 195 | * @param int range 数值的最大值即范围 196 | **/ 197 | void radixCountSort(int arr[], int out[], int origin[], int length, int range) 198 | { 199 | int tmp[range], i; 200 | //初始化 201 | for (i = 0; i < range + 1; ++i) 202 | tmp[i] = 0; 203 | //计算数值出现的次数 204 | for (i = 0; i < length; ++i) 205 | tmp[arr[i]] = tmp[arr[i]] + 1; 206 | //计算数字的下标 207 | for (i = 1; i < range + 1; ++i){ 208 | tmp[i] = tmp[i] + tmp[i-1]; 209 | } 210 | //排序结果 211 | for(i = length - 1; i > -1; i--) 212 | { 213 | out[tmp[arr[i]] - 1] = origin[i]; //注意tmp[arr[i]] - 1必须-1,因为计算数字的下标的时候出来的是实际数组的下标+1 214 | tmp[arr[i]] = tmp[arr[i]] - 1; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /algorithm/sort/sort.h: -------------------------------------------------------------------------------- 1 | #ifndef _SORT_H 2 | #define _SORT_H 3 | //插入排序 4 | void insertSort(int arr[], int length); 5 | 6 | //归并排序 7 | void mergeSort(int arr[], int start, int end); 8 | //合并数组 9 | void merge(int arr[], int start, int mid, int end); 10 | 11 | //快速排序 12 | void quickSort(int arr[], int start, int end); 13 | //快速排序切分 14 | int partition(int arr[], int start, int end); 15 | 16 | //冒泡排序 17 | void bubbleSort(int arr[], int length); 18 | 19 | //计数排序法 20 | void countSort(int arr[], int out[], int length, int range); 21 | 22 | //基数排序法 23 | void radixSort(int arr[], int output[], int length); 24 | 25 | // 基数排序用到的计数排序法 26 | void radixCountSort(int arr[], int out[], int origin[], int length, int range); 27 | 28 | //打印数组数据 29 | void printData(int *arr, int length, char *s); 30 | 31 | //求最大值 32 | int max(int arr[], int length); 33 | #endif //_SORT_H 34 | 35 | -------------------------------------------------------------------------------- /dataStructure/bitTree/bittree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bittree.h" 4 | 5 | //栈的初始化 6 | Status initStack(Stack *stack) 7 | { 8 | stack->base = (BitTNode *) malloc(sizeof(BitTNode) * STACK_INIT_SIZE); 9 | if(!stack->base) exit(ERROR); 10 | stack->top = stack->base; 11 | stack->size = STACK_INIT_SIZE; 12 | return OK; 13 | } 14 | 15 | //判断是否为空栈 16 | Status isEmpty(Stack *s) 17 | { 18 | return s->top == s->base; 19 | } 20 | 21 | //获取栈顶指针,空栈返回error 22 | Status getTop(Stack *s, BitTNode *e) 23 | { 24 | if(s->top == s->base) return ERROR; 25 | e = (s->top - 1); 26 | return OK; 27 | } 28 | 29 | //入栈 30 | Status push(Stack *s, BitTNode e) 31 | { 32 | if(s->top - s->base >= s->size) 33 | { 34 | s->base = (BitTNode *) realloc( s->base, (s->size + STACK_INCREMENT) * sizeof(BitTNode)); 35 | if(!s->base) exit(ERROR); 36 | s->top = s->base + s->size; 37 | s->size += STACK_INCREMENT; 38 | } 39 | *s->top++ = e; 40 | return OK; 41 | } 42 | 43 | //出栈 44 | Status pop(Stack *s, BitTNode *e) 45 | { 46 | if(s->top == s->base) return ERROR; 47 | *e = * --s->top; 48 | return OK; 49 | } 50 | 51 | //生成节点 52 | BitTNode* makeNode(TElemType e) 53 | { 54 | BitTNode* temp = (BitTNode*)malloc(sizeof(BitTNode)); 55 | temp->lChild = temp->rChild = NULL; 56 | temp->data = e; 57 | return temp; 58 | } 59 | 60 | //树的初始化 61 | Status initBitTree(BitTNode *t) 62 | { 63 | t->data = ROOT_VALUE; 64 | t->lChild = t->rChild = NULL; 65 | return OK; 66 | } 67 | 68 | //搜索数据所在节点 69 | //用先序非递归遍历查找 70 | Status searchNode(BitTNode* t, TElemType e, BitTNode *res) 71 | { 72 | if(t == NULL) return ERROR; 73 | Stack s; 74 | BitTNode* p = t; 75 | BitTNode tmp; 76 | initStack(&s); 77 | push(&s, *t); 78 | while(!isEmpty(&s) || p) 79 | { 80 | while(p) 81 | { 82 | push(&s, *p); 83 | p = p->lChild; 84 | } 85 | 86 | if(!isEmpty(&s)) 87 | { 88 | pop(&s, &tmp); 89 | if(tmp.data == e) { 90 | *res = tmp; 91 | return OK; 92 | } 93 | p = tmp.rChild; 94 | } 95 | } 96 | return ERROR; 97 | } 98 | 99 | //插入数据 100 | Status insertNode(BitTNode* t, TElemType e) 101 | { 102 | if(t== NULL) { 103 | return ERROR; 104 | } 105 | if(e < (t->data)) 106 | { 107 | if(t->lChild == NULL) { 108 | t->lChild = makeNode(e); 109 | return OK; 110 | } else { 111 | insertNode(t->lChild, e); 112 | } 113 | } else { 114 | if(t->rChild == NULL) { 115 | t->rChild = makeNode(e); 116 | return OK; 117 | } else { 118 | insertNode(t->rChild, e); 119 | } 120 | } 121 | return OK; 122 | } 123 | 124 | //先序遍历 125 | Status preOrderTraverse(BitTNode* t, Status (*visit)(TElemType e)) 126 | { 127 | if(t) { 128 | if(visit(t->data)) 129 | if(preOrderTraverse(t->lChild, visit)) 130 | if(preOrderTraverse(t->rChild, visit)) return OK; 131 | } 132 | return OK; 133 | } 134 | 135 | //中序遍历 136 | Status inOrderTraverse(BitTNode* t, Status (*visit)(TElemType e)) 137 | { 138 | if(t) { 139 | if(preOrderTraverse(t->lChild, visit)) 140 | if(visit(t->data)) 141 | if(preOrderTraverse(t->rChild, visit)) return OK; 142 | } 143 | return OK; 144 | } 145 | 146 | //后序遍历 147 | Status postOrderTraverse(BitTNode* t, Status (*visit)(TElemType e)) 148 | { 149 | if(t) { 150 | if(preOrderTraverse(t->lChild, visit)) 151 | if(preOrderTraverse(t->rChild, visit)) 152 | if(visit(t->data)) return OK; 153 | } 154 | return OK; 155 | } 156 | 157 | 158 | //print 159 | Status printData(TElemType e) 160 | { 161 | printf("%d ", e); 162 | return OK; 163 | } 164 | -------------------------------------------------------------------------------- /dataStructure/bitTree/bittree.h: -------------------------------------------------------------------------------- 1 | #ifndef _BITTREE_H 2 | #define _BITTREE_H 3 | #define OK 1 4 | #define ERROR 0 5 | #define ROOT_VALUE 30 //根的初始值 6 | typedef int TElemType;//元素类型 7 | typedef int Status; //状态 8 | 9 | //树节点 10 | typedef struct bitTNode { 11 | TElemType data; 12 | struct bitTNode *lChild, *rChild; 13 | } BitTNode; 14 | 15 | //栈 16 | #define STACK_INIT_SIZE 10 //存储空间的初始化分配 17 | #define STACK_INCREMENT 10 //增量 18 | typedef struct 19 | { 20 | BitTNode *base;//栈底指针 21 | BitTNode *top;//栈顶指针 22 | int size; 23 | } Stack; 24 | 25 | //print 26 | Status printData(TElemType e); 27 | 28 | //栈的初始化 29 | Status initStack(Stack *s); 30 | 31 | //判断是否为空栈 32 | Status isEmpty(Stack *s); 33 | 34 | //获取栈顶指针,空栈返回error 35 | Status getTop(Stack *s, BitTNode *e); 36 | 37 | //入栈 38 | Status push(Stack *s, BitTNode e); 39 | 40 | //出栈 41 | Status pop(Stack *s, BitTNode *e); 42 | 43 | //生成节点 44 | BitTNode* makeNode(TElemType e); 45 | 46 | //创建一个有根树 47 | Status initBitTree(BitTNode *t); 48 | 49 | //搜索数据所在节点 50 | Status searchNode(BitTNode* t, TElemType e, BitTNode *res); 51 | 52 | //插入数据 53 | Status insertNode(BitTNode* t, TElemType e); 54 | 55 | //先序遍历 56 | Status preOrderTraverse(BitTNode* t, Status (*visit)(TElemType e)); 57 | 58 | //中序遍历 59 | Status inOrderTraverse(BitTNode* t, Status (*visit)(TElemType e)); 60 | 61 | //后序遍历 62 | Status postOrderTraverse(BitTNode* t, Status (*visit)(TElemType e)); 63 | 64 | 65 | 66 | #endif //_BITTREE_H -------------------------------------------------------------------------------- /dataStructure/bitTree/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bittree.h" 4 | 5 | /** 6 | * 队列测试 7 | */ 8 | int main(int argc, char const *argv[]) 9 | { 10 | int i,num; 11 | int arr[10] = {3,5,12,23,56,31,43,35,63,14}; 12 | BitTNode t; 13 | BitTNode res; 14 | initBitTree(&t); 15 | for (i = 0; i < 10; i++) 16 | { 17 | if(insertNode(&t, arr[i]) == OK) 18 | printf("in %d success\n", arr[i]); 19 | } 20 | printf("Pre Order:\n"); 21 | preOrderTraverse(&t, printData); 22 | printf("\nIn Order:\n"); 23 | inOrderTraverse(&t, printData); 24 | printf("\nPost Order:\n"); 25 | postOrderTraverse(&t, printData); 26 | printf("\ninput the number you want to find:"); 27 | scanf("%d", &num); 28 | if(searchNode(&t, num, &res) == OK) { 29 | printf("\nresult: %d\n", res.data); 30 | } else { 31 | printf("can't find num"); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /dataStructure/doubleLinkedList/dlist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dlist.h" 4 | //创建节点 5 | Node* makeNode(const int data) 6 | { 7 | Node * p = (Node *)malloc(sizeof(Node)); 8 | if( p == NULL ) 9 | { 10 | exit(1); 11 | printf("Malloc failed"); 12 | } 13 | p->data = data; 14 | p->next = NULL; 15 | p->previous = NULL; 16 | return p; 17 | } 18 | 19 | //销毁节点 20 | void destroyNode(Node* node) 21 | { 22 | free((Node *) node); 23 | } 24 | 25 | //带头节点的单链表 26 | void dInit(Dlist * list) 27 | { 28 | list->head = makeNode(INI_MIN); 29 | } 30 | 31 | //按顺序插入 32 | bool dInsert(Dlist * list, const int data) 33 | { 34 | Node * ptem = list->head; 35 | Node* current; 36 | Node * node; 37 | node = makeNode(data); 38 | if(ptem->data > data) 39 | { 40 | list->head = node; 41 | node->next = ptem; 42 | ptem->previous = node; 43 | } else { 44 | while((current = ptem->next) != NULL && current->data < data ) 45 | ptem = ptem->next; 46 | 47 | ptem->next = node; 48 | node->previous = ptem; 49 | if( current != NULL) 50 | { 51 | node->next = current; 52 | current->previous = node; 53 | } 54 | } 55 | return true; 56 | } 57 | 58 | 59 | //移除节点 60 | bool dRemove(Dlist * list, const int key) 61 | { 62 | Node* previous = list->head; 63 | Node* current; 64 | //删除头结点 65 | if( previous->data == key ) 66 | { 67 | list->head = previous->next; 68 | return true; 69 | } 70 | //找到删除节点 71 | while( ( current = previous->next ) != NULL && current->data != key) 72 | previous = previous->next; 73 | 74 | if(current != NULL) 75 | { 76 | if (current->next != NULL) 77 | { 78 | previous->next = current->next; 79 | current->next->previous = previous; 80 | } else { 81 | previous->next = NULL; 82 | } 83 | free( current ); 84 | } 85 | return true; 86 | } 87 | 88 | //修改,先删后插入,因为这是有序链表 89 | bool dModify(Dlist * list, const int key, const int data) 90 | { 91 | if( dRemove(list, key) ) 92 | dInsert(list, data); 93 | else 94 | return false; 95 | return true; 96 | } 97 | 98 | //找到返回关键字的节点,否则返回null指针 99 | Node* dFind(Dlist * list, const int key) 100 | { 101 | Node * current = list->head; 102 | while ( (current = current->next) != NULL && current->data != key) 103 | if( current->data > key ) 104 | return NULL; 105 | return current; 106 | } 107 | 108 | //遍历 109 | void dTreaverse(Dlist * dlist, void (*func) (Node* p)) 110 | { 111 | Node * current = dlist->head; 112 | func(current); 113 | while ( (current = current->next) != NULL ) 114 | func(current); 115 | } 116 | 117 | //销毁节点 118 | void dDestrory(Dlist * list) 119 | { 120 | dTreaverse(list, destroyNode); 121 | free(list->head); 122 | } 123 | 124 | //print 125 | void printData(Node * p) 126 | { 127 | printf("%d ", p->data); 128 | } 129 | -------------------------------------------------------------------------------- /dataStructure/doubleLinkedList/dlist.h: -------------------------------------------------------------------------------- 1 | #ifndef _DLIST_H 2 | #define _DLIST_H 3 | 4 | #define INI_MIN 0 5 | //定义布尔型 6 | typedef enum 7 | { 8 | false, true 9 | } bool; 10 | //节点 11 | typedef struct node 12 | { 13 | int data; 14 | struct node * previous; 15 | struct node * next; 16 | } Node; 17 | 18 | //链表 19 | typedef struct dlist 20 | { 21 | Node * head; 22 | } Dlist; 23 | 24 | Node* makeNode(const int data); //生成节点 25 | void destroyNode(Node * node); //销毁节点 26 | 27 | void dInit(Dlist * list);//初始化 28 | bool dInsert(Dlist * list, const int data); //插入 29 | bool dRemove(Dlist * list, const int key); //删除 30 | bool dModify(Dlist * list, const int key, const int data); //修改 31 | Node* dFind(Dlist * list, const int key); //查找 32 | void dTreaverse(Dlist * list, void (*func)(Node* p)); //遍历 33 | void dDestroy(Dlist * list); //销毁 34 | void printData(Node* p); //print 35 | 36 | #endif //_DLIST_H 37 | -------------------------------------------------------------------------------- /dataStructure/doubleLinkedList/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dlist.h" 4 | 5 | /** 6 | * 有序双链表测试 7 | */ 8 | int main(int argc, char const *argv[]) 9 | { 10 | Dlist nlist; 11 | int num; 12 | dInit(&nlist); //初始化 13 | for(num = 1; num < 10; num++) 14 | { 15 | dInsert(&nlist, num); //插入 16 | } 17 | dTreaverse(&nlist, printData);//遍历打印data 18 | printf("\nremove:3\n"); 19 | dRemove(&nlist, 3); //移除 20 | dTreaverse(&nlist, printData); 21 | printf("\nmodify:8 to 44\n"); 22 | dModify(&nlist, 8, 44);//修改 23 | dTreaverse(&nlist, printData); 24 | 25 | //查找 26 | Node* node = dFind(&nlist, 6); 27 | printf("\nfind:%d previous:%d next:%d\n", node->data, node->previous->data, node->next->data); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /dataStructure/hashTable/hashtable.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hashTable.h" 4 | 5 | //散列函数--除法散列法 6 | unsigned hash(char *key) 7 | { 8 | unsigned hashVal; 9 | char *tmp = key; 10 | for (hashVal = 0; *key != '\0'; key++) 11 | { 12 | hashVal = *key + 31 * hashVal; 13 | } 14 | hashVal = 2; 15 | return hashVal; 16 | } 17 | 18 | //查询key 19 | Nodelist *search(char *key) 20 | { 21 | Nodelist *np; 22 | for (np = hashTable[hash(key)]; np != NULL; np = np->next) 23 | { 24 | if(strcmp(key, np->key) == 0) 25 | return np; 26 | } 27 | return NULL; 28 | } 29 | 30 | //插入到哈希表 31 | Nodelist *put(char *key, char *value) 32 | { 33 | Nodelist *np; 34 | unsigned hashVal; 35 | if((np = search(key)) == NULL) 36 | { 37 | np = (Nodelist *) malloc(sizeof(Nodelist)); 38 | if(np == NULL || (np->key = (char *)key) == NULL) 39 | return NULL; 40 | np->next = NULL; 41 | hashVal = hash(key); 42 | //如果不同key散列到同一个值,则用链表存起来 43 | if(hashTable[hashVal] == NULL) { 44 | hashTable[hashVal] = np; 45 | }else { 46 | Nodelist *npTmp = hashTable[hashVal], *preNp; 47 | while(npTmp != NULL) 48 | { 49 | preNp = npTmp; 50 | npTmp = npTmp->next; 51 | } 52 | preNp->next = np; 53 | } 54 | } else{ 55 | free((void*)np->value); 56 | } 57 | if ((np->value = (char *)value) == NULL) 58 | return NULL; 59 | return np; 60 | } 61 | 62 | //根据key获取值 63 | void get(char *key) 64 | { 65 | Nodelist *np; 66 | unsigned hashVal = hash(key); 67 | np = (Nodelist *)hashTable[hashVal]; 68 | while(np != NULL) 69 | { 70 | if(strcmp(key, np->key) == 0) { 71 | printf("key:%s value:%s\n", key, np->value); 72 | break; 73 | } else { 74 | np = np->next; 75 | } 76 | } 77 | if(np == NULL) printf("the key "); 78 | } -------------------------------------------------------------------------------- /dataStructure/hashTable/hashtable.h: -------------------------------------------------------------------------------- 1 | #ifndef _HASHTABLE_H 2 | #define _HASHTABLE_H 3 | 4 | #define HASHSIZE 101 5 | 6 | //哈希表元素 7 | typedef struct nodelist 8 | { 9 | struct nodelist *next; //链表法的链表 10 | char *key; //哈希的key 11 | char *value; //哈希的值 12 | } Nodelist; 13 | 14 | //哈希表 15 | static Nodelist *hashTable[HASHSIZE]; 16 | 17 | 18 | //散列函数--除法散列法 19 | unsigned hash(char *key); 20 | 21 | //查询key 22 | Nodelist *search(char *key); 23 | 24 | //插入到哈希表 25 | Nodelist *put(char *key, char *value); 26 | 27 | //根据key获取值 28 | void get(char *key); 29 | 30 | #endif //_HASHTABLE_H 31 | 32 | -------------------------------------------------------------------------------- /dataStructure/hashTable/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hashTable.h" 4 | 5 | int main(int argc, char const *argv[]) 6 | { 7 | put("a", "1"); 8 | put("b", "11"); 9 | get("a"); 10 | get("b"); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /dataStructure/linkedList/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "slist.h" 4 | 5 | /** 6 | * 有序单链表测试 7 | */ 8 | int main(int argc, char const *argv[]) 9 | { 10 | Slist nlist; 11 | int num; 12 | sInit(&nlist); //初始化 13 | for(num = 1; num < 10; num++) 14 | { 15 | sInsert(&nlist, num); //插入 16 | } 17 | sTreaverse(&nlist, printData);//遍历打印data 18 | sRemove(&nlist, 3); //移除 19 | printf("\n"); 20 | sTreaverse(&nlist, printData); 21 | sModify(&nlist, 8, 44);//修改 22 | printf("\n"); 23 | sTreaverse(&nlist, printData); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /dataStructure/linkedList/slist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "slist.h" 5 | 6 | //创建节点 7 | Node* makeNode(const int data) 8 | { 9 | Node * p = (Node *)malloc(sizeof(Node)); 10 | assert(p != NULL); 11 | p->data = data; 12 | p->next = NULL; 13 | return p; 14 | } 15 | 16 | //销毁节点 17 | void destroyNode(Node* node) 18 | { 19 | free((Node *) node); 20 | } 21 | 22 | //带头节点的单链表 23 | void sInit(Slist * list) 24 | { 25 | list->head = makeNode(INI_MIN); 26 | } 27 | 28 | //按顺序插入 29 | bool sInsert(Slist * list, const int data) 30 | { 31 | Node * ptem = list->head; 32 | Node* current; 33 | Node * node; 34 | node = makeNode(data); 35 | if(ptem->data > data) 36 | { 37 | list->head = node; 38 | node->next = ptem; 39 | } else { 40 | while((current = ptem->next) != NULL && current->data < data ) 41 | ptem = ptem->next; 42 | ptem->next = node; 43 | } 44 | return true; 45 | } 46 | 47 | //移除节点 48 | bool sRemove(Slist * list, const int key) 49 | { 50 | Node* previous = list->head; 51 | Node* current; 52 | //找到删除节点 53 | while( ( current = previous->next ) != NULL && current->data != key) 54 | previous = previous->next; 55 | if ( current == NULL ) 56 | return false; 57 | previous->next = current->next; 58 | free( current ); 59 | return true; 60 | } 61 | 62 | //修改,先删后插入,因为这是有序链表 63 | bool sModify(Slist * list, const int key, const int data) 64 | { 65 | if( sRemove(list, key) ) 66 | sInsert(list, data); 67 | else 68 | return false; 69 | return true; 70 | } 71 | 72 | //找到返回关键字的节点,否则返回null指针 73 | Node* sFind(Slist * list, const int key) 74 | { 75 | Node * current = list->head; 76 | while ( (current = current->next) != NULL && current->data != key) 77 | if( current->data > key ) 78 | return NULL; 79 | return current; 80 | } 81 | 82 | //遍历 83 | void sTreaverse( Slist * slist, void (*func) (Node* p) ) 84 | { 85 | Node * current = slist->head; 86 | func(current); 87 | while ( (current = current->next) != NULL ) 88 | func(current); 89 | } 90 | 91 | //销毁节点 92 | void sDestrory(Slist * list) 93 | { 94 | sTreaverse(list, destroyNode); 95 | free(list->head); 96 | } 97 | 98 | //print 99 | void printData(Node * p) 100 | { 101 | printf("%d ", p->data); 102 | } -------------------------------------------------------------------------------- /dataStructure/linkedList/slist.h: -------------------------------------------------------------------------------- 1 | #ifndef _SLIST_H 2 | #define _SLIST_H 3 | 4 | #define INI_MIN 0 5 | //定义布尔型 6 | typedef enum 7 | { 8 | false, true 9 | } bool; 10 | //节点 11 | typedef struct node 12 | { 13 | int data; 14 | struct node * next; 15 | } Node; 16 | 17 | //链表 18 | typedef struct slist 19 | { 20 | Node * head; 21 | } Slist; 22 | 23 | Node* makeNode(const int data); //生成节点 24 | void destroyNode(Node * node); //销毁节点 25 | 26 | void sInit(Slist * list);//初始化 27 | bool sInsert(Slist * list, const int data); //插入 28 | bool sRemove(Slist * list, const int key); //删除 29 | bool sModify(Slist * list, const int key, const int data); //修改 30 | Node* sFind(Slist * list, const int key); //查找 31 | void sTreaverse(Slist * list, void (*func)(Node * p)); //遍历 32 | void sDestroy(Slist * list); //销毁 33 | void printData(Node* p); //print 34 | 35 | #endif //_SLIST_H 36 | -------------------------------------------------------------------------------- /dataStructure/queue/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "queue.h" 4 | 5 | /** 6 | * 队列测试 7 | */ 8 | int main(int argc, char const *argv[]) 9 | { 10 | LinkQueue q; 11 | int i = 0; 12 | QElemType e; 13 | if(initQueue(&q) != OK) return ERROR; 14 | //进队列 15 | for (i = 0; i < 10; ++i) 16 | { 17 | if(in(&q, i) == OK) 18 | printf("in %d success\n", i); 19 | } 20 | //遍历打印 21 | printf("Traverse queue:\n"); 22 | queueTraverse(&q, printData); 23 | printf("\n"); 24 | //出队列 25 | for (i = 0; i < 10; ++i) 26 | { 27 | out(&q, &e); 28 | printf("out: %d success \n", e); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dataStructure/queue/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "queue.h" 4 | //队列的初始化 5 | Status initQueue(LinkQueue *q) 6 | { 7 | q->front = q->rear = (QueuePtr) malloc(sizeof(QNode)); 8 | if(!q->front) exit(OVERFLOW); 9 | q->front->next = NULL; 10 | return OK; 11 | } 12 | 13 | //销毁队列 14 | Status destroyQueue(LinkQueue *q) 15 | { 16 | while(q->front) 17 | { 18 | q->rear = q->front->next; 19 | free(q->front); 20 | q->front = q->rear; 21 | } 22 | return OK; 23 | } 24 | 25 | //判断是否为空队列 26 | Status isEmpty(LinkQueue *q) 27 | { 28 | if(q->front == q->rear) return OK; 29 | else return NOPE; 30 | } 31 | 32 | //获取队列的长度 33 | int queueLength(LinkQueue q) 34 | { 35 | return 0; 36 | } 37 | 38 | //获取队头指针 39 | Status getHead(LinkQueue *q, QElemType *e) 40 | { 41 | return OK; 42 | } 43 | 44 | //插入 45 | Status in(LinkQueue *q, QElemType e) 46 | { 47 | QueuePtr p = (QueuePtr) malloc(sizeof(QNode)); 48 | if(!p) exit(OVERFLOW); 49 | p->data = e; 50 | p->next = NULL; 51 | q->rear->next = p; 52 | q->rear = p; 53 | return OK; 54 | } 55 | 56 | //出队列,并返回队头元素到*e 57 | Status out(LinkQueue *q, QElemType *e) 58 | { 59 | if(q->front == q->rear) return ERROR; 60 | QueuePtr p = (QueuePtr) malloc(sizeof(QNode)); 61 | if(!p) exit(OVERFLOW); 62 | p = q->front->next; 63 | *e = p->data; 64 | q->front->next = p->next; 65 | if(q->rear == p) q->rear = q->front; 66 | free(p); 67 | return OK; 68 | } 69 | 70 | //遍历 71 | Status queueTraverse(LinkQueue *q, void (* visit)(QElemType e)) 72 | { 73 | if(q->front == q->rear) return ERROR; 74 | QueuePtr p = (QueuePtr) malloc(sizeof(QNode)); 75 | if(!p) exit(OVERFLOW); 76 | p = q->front->next; 77 | while(1) 78 | { 79 | visit(p->data); 80 | if(p == q->rear) break; 81 | p = p->next; 82 | } 83 | return OK; 84 | } 85 | 86 | void printData(QElemType e) 87 | { 88 | printf("%d ", e); 89 | } -------------------------------------------------------------------------------- /dataStructure/queue/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUEUE_H 2 | #define _QUEUE_H 3 | 4 | #define OK 1 5 | #define NOPE 0 6 | #define ERROR 0 7 | #define OVERFLOW -2 8 | 9 | typedef int QElemType; //元素类型 10 | 11 | typedef struct qNode 12 | { 13 | QElemType data; 14 | struct qNode *next; 15 | } QNode, *QueuePtr; 16 | 17 | typedef int Status; //状态 18 | 19 | typedef struct 20 | { 21 | QueuePtr front;//队头指针,不存数据,front->next是才是真正的对头节点 22 | QueuePtr rear;//队尾指针 23 | } LinkQueue; 24 | 25 | //队列的初始化 26 | Status initQueue(LinkQueue *q); 27 | 28 | //销毁栈 29 | Status destroyQueue(LinkQueue *q); 30 | 31 | //判断是否为空栈 32 | Status isEmpty(LinkQueue *q); 33 | 34 | //获取栈的长度 35 | int queueLength(LinkQueue q); 36 | 37 | //获取栈顶指针,空栈返回error 38 | Status getHead(LinkQueue *q, QElemType *e); 39 | 40 | //插入 41 | Status in(LinkQueue *q, QElemType e); 42 | 43 | //出队 44 | Status out(LinkQueue *q, QElemType *e); 45 | 46 | //遍历 47 | Status queueTraverse(LinkQueue *q, void (* visit)(QElemType e)); 48 | 49 | //print 50 | void printData(QElemType e); 51 | #endif //_QUEUE_H 52 | -------------------------------------------------------------------------------- /dataStructure/stack/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | /** 6 | * 有序栈测试 7 | */ 8 | int main(int argc, char const *argv[]) 9 | { 10 | Stack s; 11 | SElemTpye e; 12 | int i; 13 | initStack(&s); 14 | for (i = 1; i < 5; ++i) 15 | { 16 | scanf("%d", &e); 17 | if(push(&s, e) == OK) 18 | printf("push %d success\n", e); 19 | } 20 | printf("traverse this stack:", e); 21 | stackTraverse(&s, printData); 22 | printf("\n", e); 23 | for (i = 1; i < 5; ++i) 24 | { 25 | if(pop(&s, &e) == OK) 26 | printf("pop %d success\n", e); 27 | } 28 | destroyStack(&s); 29 | } 30 | -------------------------------------------------------------------------------- /dataStructure/stack/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | Status initStack(Stack *stack) 6 | { 7 | stack->base = (SElemTpye *) malloc(sizeof(SElemTpye) * STACK_INIT_SIZE); 8 | if(!stack->base) exit(ERROR); 9 | stack->top = stack->base; 10 | stack->size = STACK_INIT_SIZE; 11 | return OK; 12 | } 13 | 14 | Status getTop(Stack *s, SElemTpye *e) 15 | { 16 | if(s->top == s->base) return ERROR; 17 | e = (s->top - 1); 18 | return OK; 19 | } 20 | 21 | Status push(Stack *s, SElemTpye e) 22 | { 23 | if(s->top - s->base >= s->size) 24 | { 25 | s->base = (SElemTpye *) realloc( s->base, (s->size + STACK_INCREMENT) * sizeof(SElemTpye)); 26 | if(!s->base) exit(ERROR); 27 | s->top = s->base + s->size; 28 | s->size += STACK_INCREMENT; 29 | } 30 | *s->top++ = e; 31 | return OK; 32 | } 33 | 34 | Status pop(Stack *s, SElemTpye *e) 35 | { 36 | if(s->top == s->base) return ERROR; 37 | *e = * --s->top; 38 | return OK; 39 | } 40 | 41 | Status destroyStack(Stack *s) 42 | { 43 | free((Stack *)s); 44 | } 45 | 46 | Status isEmpty(Stack *s) 47 | { 48 | return s->top == s->base; 49 | } 50 | 51 | int stackLength(Stack *s) 52 | { 53 | if(s->top == s->base) return ERROR; 54 | return s->size; 55 | } 56 | 57 | Status stackTraverse(Stack *s, void (* visit)(SElemTpye *e)) 58 | { 59 | SElemTpye *e; 60 | e = s->top; 61 | while(e != s->base) 62 | visit(-- e); 63 | return OK; 64 | } 65 | 66 | void printData(SElemTpye *e) 67 | { 68 | printf("%d ", *e); 69 | } -------------------------------------------------------------------------------- /dataStructure/stack/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef _STACK_H 2 | #define _STACK_H 3 | 4 | #define OK 1 5 | #define ERROR 0 6 | #define OVERFLOW -2 7 | 8 | #define STACK_INIT_SIZE 10 //存储空间的初始化分配 9 | #define STACK_INCREMENT 10 //增量 10 | 11 | typedef int SElemTpye; //元素类型 12 | typedef int Status; //元素类型 13 | 14 | typedef struct 15 | { 16 | SElemTpye *base;//栈底指针 17 | SElemTpye *top;//栈顶指针 18 | int size; 19 | } Stack; 20 | 21 | //栈的初始化 22 | Status initStack(Stack *s); 23 | 24 | //销毁栈 25 | Status destroyStack(Stack *s); 26 | 27 | //判断是否为空栈 28 | Status isEmpty(Stack *s); 29 | 30 | //获取栈的长度 31 | int stackLength(Stack *s); 32 | 33 | //获取栈顶指针,空栈返回error 34 | Status getTop(Stack *s, SElemTpye *e); 35 | 36 | //入栈 37 | Status push(Stack *s, SElemTpye *e); 38 | 39 | //出栈 40 | Status pop(Stack *s, SElemTpye *e); 41 | 42 | //遍历 43 | Status stackTraverse(Stack *s, void (* visit)(SElemTpye *e)); 44 | 45 | void printData(SElemTpye *e); //print 46 | #endif //_STACK_H 47 | --------------------------------------------------------------------------------