commit
5e21552151
53
c-cpp/15_bsearch/bsearch_c/sqrt.c
Normal file
53
c-cpp/15_bsearch/bsearch_c/sqrt.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*************************************************************************
|
||||
> File Name: sqrt.c
|
||||
> Author: jinshaohui
|
||||
> Mail: jinshaohui789@163.com
|
||||
> Time: 18-10-31
|
||||
> Desc:
|
||||
************************************************************************/
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
#include<stdlib.h>
|
||||
#include<assert.h>
|
||||
|
||||
|
||||
/*求解精度设置*/
|
||||
#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;
|
||||
}
|
||||
|
190
c-cpp/16_bsearch/bsearch.c
Normal file
190
c-cpp/16_bsearch/bsearch.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*************************************************************************
|
||||
> File Name: bsearch.c
|
||||
> Author: jinshaohui
|
||||
> Mail: jinshaohui789@163.com
|
||||
> Time: 18-10-21
|
||||
> Desc:
|
||||
************************************************************************/
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<assert.h>
|
||||
|
||||
/*二分查找算法的变形问题
|
||||
*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;
|
||||
}
|
345
c-cpp/17_skiplist/skiplist_c/skiplist.c
Normal file
345
c-cpp/17_skiplist/skiplist_c/skiplist.c
Normal file
@ -0,0 +1,345 @@
|
||||
/*************************************************************************
|
||||
> File Name: skiplist.c
|
||||
> Author: jinshaohui
|
||||
> Mail: jinshaohui789@163.com
|
||||
> Time: 18-10-31
|
||||
> Desc:
|
||||
************************************************************************/
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include<assert.h>
|
||||
#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;
|
||||
}
|
33
c-cpp/17_skiplist/skiplist_c/skiplist.h
Normal file
33
c-cpp/17_skiplist/skiplist_c/skiplist.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user