数据结构 哈希表 五大排序算法 二分查找(折半查找)
1、哈希表
1.1创建哈希表
哈希表:
将数据通过哈希算法映射称为一个键值
存时在键值对应的位置存储
取时通过键值对应的位置查找
哈希冲突(哈希碰撞):多个数据通过哈希算法映射成同一个键值
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "list.h"
#define INDEX 10
struct list_head hashtable[INDEX];
typedef struct Data
{
struct list_head node;
int data;
}Data_t;
//按照顺序插入
int compare(struct list_head *pNewNode, struct list_head *pTmpNode)
{
if (NULL == pTmpNode)
{
return 1;
}
return list_entry(pNewNode, Data_t, node)->data - list_entry(pTmpNode, Data_t, node)->data;
}
//插入哈希表
int InsertHashTable(int Num)
{
int index = 0;
Data_t *pNewNode = NULL;
//申请节点
pNewNode = malloc(sizeof(Data_t));
if (NULL == pNewNode)
{
return -1;
}
pNewNode->data = Num;
//获得插入数据的键值
index = Num % INDEX;
//插入数据
list_add_order(&pNewNode->node, &hashtable[index], compare);
return 0;
}
//打印哈希表
int ShowHashTable(void)
{
int index = 0;
Data_t *pData = NULL;
for (index = 0; index < INDEX; index++)
{
printf("%d:", index);
list_for_each_entry(pData, &hashtable[index], node)
{
printf("%d ", pData->data);
}
printf("\n");
}
return 0;
}
//初始化所有节点
int InitHashTable(void)
{
int i = 0;
for (i = 0; i < INDEX; i++)
{
INIT_LIST_HEAD(&hashtable[i]);
}
return 0;
}
//查找数据
int FindHashTable(int Num)
{
int index = 0;
Data_t *pData = NULL;
int ret = 0;
index = Num % INDEX;
list_for_each_entry(pData, &hashtable[index], node)
{
if (pData->data == Num)
{
ret = 1;
break;
}
if (pData->data > Num)
{
ret = 0;
break;
}
}
return ret;
}
//销毁Hash表
int DestroyHashTable()
{
int i = 0;
Data_t *pTmpNode = NULL;
Data_t *pNextNode = NULL;
for (i = 0; i < INDEX; i++)
{
list_for_each_entry_safe(pTmpNode, pNextNode, &hashtable[i], node)
{
free(pTmpNode);
}
}
return 0;
}
int main(void)
{
int i = 0;
int tmp = 0;
srand(time(NULL));
InitHashTable();
for (i = 0; i < 30; i++)
{
InsertHashTable(rand() % 100);
}
ShowHashTable();
printf("请输入要查找的数据:\n");
scanf("%d", &tmp);
if (FindHashTable(tmp))
{
printf("%d 存在!\n", tmp);
}
else
{
printf("%d 不存在!\n", tmp);
}
DestroyHashTable();
return 0;
}
2、五大排序
1、1冒泡排序(时间复杂度O(N^2))
int BubbleSort(int *pArray, int MaxLen)
{
int j = 0;
int i = 0;
int temp = 0;
for (j = 0; j < MaxLen-1; j++)
{
for (i = 0; i < MaxLen-1-j; i++)
{
if (pArray[i] > pArray[i+1])
{
temp = pArray[i];
pArray[i] = pArray[i+1];
pArray[i+1] = temp;
}
}
}
return 0;
}
1、2选择排序(时间复杂度O(N^2))
int SelectSort(int *pArray, int MaxLen)
{
int Min = 0;
int Temp = 0;
int i = 0;
int j = 0;
for (j = 0; j < MaxLen-1; j++)
{
Min = j;
for (i = j+1; i < MaxLen; i++)
{
if (pArray[i] < pArray[Min])
{
Min = i;
}
}
if (Min != j)
{
Temp = pArray[j];
pArray[j] = pArray[Min];
pArray[Min] = Temp;
}
}
return 0;
}
1、3插入排序(时间复杂度O(N^2))
int InsertSort(int *pArray, int MaxLen)
{
int i = 0;
int j = 0;
int Temp = 0;
for (j = 1; j < MaxLen; j++)
{
Temp = pArray[j];
for (i = j; i > 0 && Temp < pArray[i-1]; i--)
{
pArray[i] = pArray[i-1];
}
pArray[i] = Temp;
}
return 0;
}
1、4希尔排序(时间复杂度O(nlogn))
int ShellSort(int *pArray, int MaxLen)
{
int step = 0;
int i = 0;
int j = 0;
int temp = 0;
for (step = MaxLen / 2; step > 0; step /= 2)
{
for (j = step; j < MaxLen; j++)
{
temp = pArray[j];
for (i = j; i >= step && temp < pArray[i-step]; i -= step)
{
pArray[i] = pArray[i-step];
}
pArray[i] = temp;
}
}
return 0;
}
1、5快速排序(时间复杂度(O(n))
int QuickSort(int *pArray, int Low, int High)
{
int Key = 0;
int j = High;
int i = Low;
Key = pArray[Low];
while (i < j)
{
while (i < j && pArray[j] >= Key)
{
j--;
}
pArray[i] = pArray[j];
while (i < j && pArray[i] <= Key)
{
i++;
}
pArray[j] = pArray[i];
}
pArray[i] = Key;
if (i-1 > Low)
{
QuickSort(pArray, Low, i-1);
}
if (i+1 < High)
{
QuickSort(pArray, i+1, High);
}
return 0;
}
3、二分查找(需要在以经排好序的情况下使用)
int MidSearch(int *pArray, int Low, int High, int tmpdata)
{
int Mid = 0;
if (Low > High)
{
return -1;
}
Mid = (Low + High) / 2;
if (tmpdata < pArray[Mid])
{
return MidSearch(pArray, Low, Mid-1, tmpdata);
}
else if (tmpdata > pArray[Mid])
{
return MidSearch(pArray, Mid+1, High, tmpdata);
}
else if (tmpdata == pArray[Mid])
{
return Mid;
}
}