From 84602b7fd224673ea693f5a1ceb728f260c2c250 Mon Sep 17 00:00:00 2001 From: jinshaohui Date: Wed, 31 Oct 2018 11:06:01 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BA=8C=E5=88=86=E6=9F=A5=E6=89=BE?= =?UTF-8?q?=E6=B1=82=E5=B9=B3=E6=96=B9=E6=A0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- c-cpp/15_bsearch/bsearch_c/sqrt.c | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 c-cpp/15_bsearch/bsearch_c/sqrt.c diff --git a/c-cpp/15_bsearch/bsearch_c/sqrt.c b/c-cpp/15_bsearch/bsearch_c/sqrt.c new file mode 100644 index 0000000..7c7c3d4 --- /dev/null +++ b/c-cpp/15_bsearch/bsearch_c/sqrt.c @@ -0,0 +1,53 @@ +/************************************************************************* + > File Name: sqrt.c + > Author: jinshaohui + > Mail: jinshaohui789@163.com + > Time: 18-10-31 + > Desc: + ************************************************************************/ +#include +#include +#include +#include + + +/*求解精度设置*/ +#define E 0.000001 +double mybsearch(double num) +{ + double start = 1.0; + double end = num; + double mid = 0.0; + while(1) + { + mid = (start + end)/2; + if(((mid*mid - num) <= E) && ((mid*mid - num) >= -E)) + { + return mid; + } + + if ((mid*mid - num) > E) + { + end = mid; + } + else + { + start = mid; + } + } + + return 0; +} + + +int main() +{ + double num = 0.0; + + /*这里需要注意:double的输入方式*/ + scanf("%lf",&num); + printf("\r\n num %lf的平方根是%lf",num,mybsearch(num)); + + return 0; +} + From e713d63e3450985548a365204672ef676c8156b8 Mon Sep 17 00:00:00 2001 From: jinshaohui Date: Wed, 31 Oct 2018 12:39:35 +0800 Subject: [PATCH 2/3] =?UTF-8?q?add=20by=20jinshaohui=20for=20=E4=BA=8C?= =?UTF-8?q?=E5=88=86=E6=9F=A5=E6=89=BE=E5=8F=98=E5=BD=A2=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- c-cpp/16_bsearch/bsearch.c | 190 +++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 c-cpp/16_bsearch/bsearch.c diff --git a/c-cpp/16_bsearch/bsearch.c b/c-cpp/16_bsearch/bsearch.c new file mode 100644 index 0000000..17e06fd --- /dev/null +++ b/c-cpp/16_bsearch/bsearch.c @@ -0,0 +1,190 @@ +/************************************************************************* + > File Name: bsearch.c + > Author: jinshaohui + > Mail: jinshaohui789@163.com + > Time: 18-10-21 + > Desc: + ************************************************************************/ +#include +#include +#include + +/*二分查找算法的变形问题 + *1、查找第一个等于给定数值的元素 + *2、查找最后一个等于给定数值的元素 + *3、查找第一个大于等于给定数值的元素 + *4、查找第一个小于等于给定数值的元素 + * */ + + + /*1、查找第一个等于给定数值的元素*/ +int mybsearch_1(int a[],int size,int value) +{ + int mid = 0; + int left = 0; + int right = size - 1; + + while(left <= right) + { + /*防止size数量太大是,(left + right)数据翻转,导致问题*/ + mid = left + ((right - left)>>1); + + if (a[mid] < value) + { + left = mid + 1; + } + else if (a[mid] > value) + { + right = mid - 1; + } + else + { + if ((mid == 0) || (a[mid - 1] != value)) + { + return mid; + } + else + { + right = mid - 1; + } + } + } + + return -1; +} + + /*2、查找最后一个等于给定数值的元素*/ +int mybsearch_2(int a[],int size,int value) +{ + int mid = 0; + int left = 0; + int right = size - 1; + + while(left <= right) + { + /*防止size数量太大是,(left + right)数据翻转,导致问题*/ + mid = left + ((right - left)>>1); + + if (a[mid] < value) + { + left = mid + 1; + } + else if (a[mid] > value) + { + right = mid - 1; + } + else + { + if ((mid == (size - 1)) || (a[mid + 1] != value)) + { + return mid; + } + else + { + left = mid + 1; + } + } + } + + return -1; +} + /*3、查找第一个大于等于给定数值的元素*/ +int mybsearch_3(int a[],int size,int value) +{ + int mid = 0; + int left = 0; + int right = size - 1; + + while(left <= right) + { + /*防止size数量太大是,(left + right)数据翻转,导致问题*/ + mid = left + ((right - left)>>1); + + if (a[mid] < value) + { + left = mid + 1; + } + else + { + /*a[mid] >= value 当mid==0 或者a[mid-1] > value 说明是第一个大于等于value*/ + if ((mid == 0) || (a[mid - 1] < value)) + { + return mid; + } + else + { + right = mid - 1; + } + } + } + + return -1; +} + + /*4、查找第一个小于等于给定数值的元素*/ +int mybsearch_4(int a[],int size,int value) +{ + int mid = 0; + int left = 0; + int right = size - 1; + + while(left <= right) + { + /*防止size数量太大是,(left + right)数据翻转,导致问题*/ + mid = left + ((right - left)>>1); + + if (a[mid] > value) + { + right = mid - 1; + } + else + { + /*a[mid] <= value 时,当前mid == size -1 数组中最大的数值; + * 或者a[mid + 1] 大于vlaue,就是mid就第一个小于等于value*/ + if ((mid == (size - 1)) || (a[mid + 1] > value)) + { + return mid; + } + else + { + left = mid + 1; + } + } + } + + return -1; +} +int main() +{ + int a[10] = {5,6,6,9,10,11,11,22,33,33}; + int data = 0; + int i = 0; + int res =0; + + printf("\r\n"); + for(i = 0; i < 10 ; i++) + { + printf("%d ",a[i]); + } + printf("\r\n"); + printf("\r\n输入一个整数"); + scanf("%d",&data); + res = mybsearch_1(a,10,data); + printf("第一个等于data[%d],下标是%d",data,res); + + printf("\r\n输入一个整数"); + scanf("%d",&data); + res = mybsearch_2(a,10,data); + printf("最后一个等于data[%d],下标是%d",data,res); + + printf("\r\n输入一个整数"); + scanf("%d",&data); + res = mybsearch_2(a,10,data); + printf("第一个大于等于data[%d],下标是%d",data,res); + + printf("\r\n输入一个整数"); + scanf("%d",&data); + res = mybsearch_2(a,10,data); + printf("第一个小等于data[%d],下标是%d",data,res); + return; +} From b72c72308feca3c37c8e0bb882f3c329ed0c9cba Mon Sep 17 00:00:00 2001 From: jinshaohui Date: Thu, 1 Nov 2018 06:54:17 +0800 Subject: [PATCH 3/3] add by jinshaohui for skip list by c --- c-cpp/17_skiplist/skiplist_c/skiplist.c | 345 ++++++++++++++++++++++++ c-cpp/17_skiplist/skiplist_c/skiplist.h | 33 +++ 2 files changed, 378 insertions(+) create mode 100644 c-cpp/17_skiplist/skiplist_c/skiplist.c create mode 100644 c-cpp/17_skiplist/skiplist_c/skiplist.h diff --git a/c-cpp/17_skiplist/skiplist_c/skiplist.c b/c-cpp/17_skiplist/skiplist_c/skiplist.c new file mode 100644 index 0000000..3a171e7 --- /dev/null +++ b/c-cpp/17_skiplist/skiplist_c/skiplist.c @@ -0,0 +1,345 @@ +/************************************************************************* + > File Name: skiplist.c + > Author: jinshaohui + > Mail: jinshaohui789@163.com + > Time: 18-10-31 + > Desc: + ************************************************************************/ +#include +#include +#include +#include +#include"./skiplist.h" + + +/*创建node节点*/ +node* skip_list_create_node(int level,int key,int value) +{ + node * tmp = NULL; + + tmp =(node *)malloc(sizeof(node) + level*sizeof(node *)); + assert(tmp != NULL); + + memset(tmp,0,sizeof(node) + level*sizeof(node*)); + tmp->key = key; + tmp->value = value; + tmp->max_level = level; + + return tmp; +} + +/*创建跳表的表头,max_level层数*/ +skiplist * skip_list_create(int max_level) +{ + int i = 0; + skiplist * list = NULL; + + list = (skiplist *)malloc (sizeof(skiplist)); + assert(list != NULL); + + list->level = 1; + list->count = 0; + + list->head = skip_list_create_node(max_level,0,0); + if(list->head == NULL) + { + + free(list); + return NULL; + } + + return list; +} + +/*skiplist 销毁*/ +void skip_list_destory(skiplist * list) +{ + int i = 0; + node * tmp = NULL; + + if((list == NULL) || (list->head == NULL)) + { + return; + } + while(list->head->next[0] != NULL) + { + tmp = list->head->next[0]; + list->head->next[0] = tmp->next[0]; + free(tmp); + } + + free(list); + return; +} + +/*插入元素获得层数,是随机产生的*/ +int skip_list_level(skiplist * list) +{ + int i = 0; + int level = 1; + for (i = 1; i < list->head->max_level; i++) + { + if ((rand()%2) == 1) + { + level++; + } + } + + return level; +} +int skip_list_insert(skiplist *list,int key,int value) +{ + int i = 0; + int level = 0; + node **update = NULL;/*用来更新每层的指针*/ + node *tmp = NULL; + node *prev = NULL; + + if (list == NULL) + { + return 1; + } + + /*申请update空间用于保存每层的指针*/ + update = (node **)malloc(sizeof(node *)*list->head->max_level); + if (update == NULL) + { + return 2; + } + + /*逐层查询节点的*/ + prev = list->head; + for (i = (list->level -1); i >= 0; i--) + { + /*初始化每level层的头指针*/ + while(((tmp = prev->next[i]) != NULL) && (tmp->key < key)) + { + prev = tmp; + } + update[i] = prev; + } + + /*当前key已经存在,返回错误*/ + if ((tmp!= NULL) && (tmp->key == key)) + { + return 3; + } + /*获取插入元素的随机层数,并更新跳表的最大层数*/ + level = skip_list_level(list); + /*创建当前数据节点*/ + tmp = skip_list_create_node(level,key,value); + if (tmp == NULL) + { + return 4; + } + + /*更新最大层数*/ + if (level > list->level) + { + for (i = list->level;i < level; i ++) + { + update[i] = list->head; + } + list->level = level; + } + + /*逐层更新节点的指针*/ + for(i = 0; i < level; i++) + { + tmp->next[i] = update[i]->next[i]; + update[i]->next[i] = tmp; + } + + list->count++; + return 0; +} + +int skip_list_delete(skiplist * list, int key ,int *value) +{ + int i = 0; + node **update = NULL;/*用来更新每层的指针*/ + node *tmp = NULL; + node *prev = NULL; + + if ((list == NULL) && (value == NULL)&& (list->count == 0)) + { + return 1; + } + /*申请update空间用于保存每层的指针*/ + update = (node **)malloc(sizeof(node *)*list->level); + if (update == NULL) + { + return 2; + } + /*逐层查询节点的*/ + prev = list->head; + for (i = (list->level -1); i >= 0; i--) + { + /*初始化每level层的头指针*/ + while(((tmp = prev->next[i]) != NULL) && (tmp->key < key)) + { + prev = tmp; + } + update[i] = prev; + } + + if ((tmp != NULL) + && (tmp->key == key)) + { + *value = tmp->value; + /*逐层删除*/ + for(i = 0; i < list->level; i++) + { + if(update[i]->next[i] == tmp) + { + update[i]->next[i] = tmp->next[i]; + } + } + + free(tmp); + tmp = NULL; + + /*更新level的层数*/ + for (i = list->level - 1; i >= 0; i++) + { + if (list->head->next[i] == NULL ) + { + list->level--; + } + else + { + break; + } + } + + list->count--; + + } + else + { + return 3;/*未找到节点*/ + } + + return 0 ; +} + +/*查询当前key是否在跳表中,如果存在返回查询的value数值,不存在返回-1*/ +int skip_list_search(skiplist *list,int key,int *value) +{ + int i = 0; + node *prev = NULL; + node *tmp = NULL; + + if((list == NULL) || (list->count == 0) || (value == NULL)) + { + return 1; + } + prev = list->head; + for(i = list->level - 1; i >= 0; i--) + { + while(((tmp = prev->next[i]) != NULL) && (tmp->key <= key)) + { + if (tmp->key == key) + { + *value = tmp->value; + return 0; + } + prev = tmp; + } + } + + return -1; +} + +void skip_list_dump(skiplist *list) +{ + int i = 0; + node *ptmp = NULL; + printf("\r\n----------------------------------------------"); + printf("\r\n skip list level[%d],count[%d]",list->level,list->count); + for(i = list->level - 1; i >= 0; i --) + { + ptmp = list->head->next[i]; + printf("\r\n level[%d]:",i); + while(ptmp != NULL) + { + printf("%d-%d ",ptmp->key,ptmp->value); + ptmp = ptmp->next[i]; + } + } + printf("\r\n----------------------------------------------"); + return; +} + +int main() +{ + int res = 0; + int key = 0; + int value = 0; + skiplist *list = NULL; + + + list = skip_list_create(5); + assert(list != NULL); + + while(1) + { + printf("\r\n 请输入key 和 value,当key = 1000时,退出输入:"); + scanf("%d%d",&key,&value); + if (key == 1000) + { + break; + } + res = skip_list_insert(list,key,value); + if (res != 0) + { + printf("\r\n skip list insert %d,failed,res=%d.",key,res); + } + } + skip_list_dump(list); + + while(1) + { + printf("\r\n 通过key 查询value的数值,当key = 1000时,退出查询"); + scanf("%d",&key); + if(key == 1000) + { + break; + } + res = skip_list_search(list,key,&value); + if (res != 0) + { + printf("\r\n skip list search %d,failed,res=%d.",key,res); + } + else + { + printf("\r\n skip list search %d,sucessful,value=%d.",key,value); + + } + } + skip_list_dump(list); + while(1) + { + printf("\r\n 通过key 删除节点,当key = 1000时,退出删除"); + scanf("%d",&key); + if(key == 1000) + { + break; + } + res = skip_list_delete(list,key,&value); + if (res != 0) + { + printf("\r\n skip list search %d,failed,res=%d.",key,res); + } + else + { + printf("\r\n skip list search %d,sucessful,value=%d.",key,value); + + } + } + + skip_list_dump(list); + skip_list_destory(list); + + return 0; +} diff --git a/c-cpp/17_skiplist/skiplist_c/skiplist.h b/c-cpp/17_skiplist/skiplist_c/skiplist.h new file mode 100644 index 0000000..217c9df --- /dev/null +++ b/c-cpp/17_skiplist/skiplist_c/skiplist.h @@ -0,0 +1,33 @@ +/************************************************************************* + > File Name: skiplist.h + > Author: jinshaohui + > Mail: jinshaohui789@163.com + > Time: 18-10-31 + > Desc: + ************************************************************************/ +#ifndef __SKIP_LIST_H__ +#define __SKIP_LIST_H__ + + +typedef struct _node +{ + int key; /*key是唯一的*/ + int value; /*存储的内容*/ + int max_level; /*当前节点最大层数*/ + struct _node *next[0];/*level层链表结构*/ +}node; + +typedef struct _skiplist +{ + int level; + int count; + node *head; +}skiplist; + +/*根据当前结构体元素的地址,获取到结构体首地址*/ +#define offsetof(TYPE,MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#define container(ptr,type,member) ({\ + const typeof( ((type *)0)->member) *__mptr = (ptr);\ + (type *) ( (char *)__mptr - offsetof(type,member));}) + +#endif