C语言实现顺序线性表(附二分查找)
具体代码如下:
- 宏定义和表结构体头文件
/*
* @Author: xgh
* @Date: 2020-05-29 17:11:55
* @LastEditTime: 2020-05-29 22:09:26
* @LastEditors: Please set LastEditors
* @Description: 宏定义和线性表结构体定义头文件
* @FilePath: \VS-CODE-C\.vscode\linearLine\.h
*/
#ifndef __DATA_H__
#define __DATA_H__
#include<stdio.h>
#include<stdlib.h>
#define SUCCESS 1 //成功
#define FAILURE 0 //失败
#define ERROER 0 //错误
//线性表储存空间的初始化分配量
#define LIST_ININ_SIZE 5
//线性表存储空间的分配增量
#define LISTINCREMENT 10
/*
*定义线性表结构
*/
typedef struct
{
int *elem; //储存空间及地址(数组指针,指向预分配数组的首地址)
int length; //当前线性表的长度
int listSize; //当前分配的存储容量
}sqList;
#endif
- 创建线性表,分配内存
/**
1. @description: 创建空顺序线性表
2. @param {sqList *L:结构体参数}
3. @return: FAILURE:失败
4. @return: SUCCESS:成功
*/
int InitList(sqList *L){
//动态分配内存
//分配成功:返回分配的内存空间的首地址
//分配失败:返回空指针
L->elem = (int *)malloc(LIST_ININ_SIZE * sizeof(int));
//判断内存分配是否成功
if(L->elem == NULL){
return FAILURE;
}
//初始化表长为0,未储存数据
L->length = 0;
//初始化存储容量
L->listSize = LIST_ININ_SIZE;
return SUCCESS;
}
- 插入元素
/**
* @description: 向线性表中第index个位置插入数据data
* @param {sqList *L:线性表}
* @param {int index: 插入的索引}
* @param {int data: 插入的数据}
* @return: FALIURE: 内存分配失败
* @return: SUCCESS: 插入数据成功
*/
int insertList_sq(sqList *L, int index, int data){
int *movePoint; //移动的地址
//判断插入的位置是否不小于表头,不大于表尾;1 <= index <= L.length + 1(合法范围)
if(index < 1 || index > L->length + 1)
return ERROER;
//判断表储存空间是否满了,满了则增加储存空间
if(L->length >= LIST_ININ_SIZE){
int *newHeader = (int *)realloc(L->elem, (LISTINCREMENT + LIST_ININ_SIZE) * sizeof(int));
//内存分配是否成功
if(newHeader == NULL)
return FAILURE;
//更新表头地址
L->elem = newHeader;
//更新表容量
L->listSize += LISTINCREMENT;
}
//获取data插入的地址
int *dataPoint = &(L->elem[index - 1]);
//将data后的数据地址往后移一位
for(movePoint = &(L->elem[L->length - 1]); movePoint >= dataPoint; movePoint--){
//将表向后移动一位
*(movePoint + 1) = *movePoint;
}
//插入数据data
*dataPoint = data;
//表长度加1
L->length += 1;
return SUCCESS;
}
- 删除元素
/**
* @description: 根据元素位置删除
* @param {sqList *L:线性表}
* @param {int index: 删除的位置}
* @return: ERROR: 删除位置错误
* @return SUCCESS: 删除成功
*/
int delList_index(sqList *L, int index){
int *movePoint; //移动的地址
//判断表是否为空
if(L->length == 0){
return ERROER;
}
//判断删除索引是否在合法范围内 1 < index < L.length
if(index < 1 || index > L->length){
return ERROER;
}
//获取删除的元素地址
int *delPoint = &(L->elem[index]);
printf("删除的元素是:%d\n", L->elem[index]);
//删除元素,指针向前移动
for(movePoint = delPoint + 1; movePoint < delPoint + (L->length - index); movePoint++){
*(movePoint - 1) = *movePoint; //将后一个地址的数据给到前一个地址
}
//删除完成后,表长度减1
L->length -= 1;
return SUCCESS;
}
- 二分查找检索线性表数据
一个数组内元素为1-100;查找60,折半为50,60是否大于50,是则在右边数据区查找,不是则在左边数据区查找,以此类推,时间复杂度为log2n
/**
* @description: 二分查找
* @param {sqlist *L:待查询的结构体}
* @param {int data:待匹配的数据}
* @return:
*/
int binary_search(sqList *L, int data){
int mid; //中间值
int left = 0; //开始下标
int right = L->length - 1; //结束下标
//判断表是否为空
if(left == right){
return ERROER;
}
while (left <= right)
{
mid = (left + right) / 2; // 计算中间值索引
if(L->elem[mid] == data){ // 中间值为待检索值
printf("找到了待检索数据%d, 索引是%d", data , mid);
return SUCCESS;
}else if (data < L->elem[mid]){ // 待检索值是否在中间值左边
right = mid - 1;
}else{ // 待检索值在中间值右边
left = mid + 1;
}
//未检索到待检索值
if(left > right){
printf("未找到待检索数据%d", data);
return FAILURE;
}
}
}
- main函数调用
int main(void){
sqList L;
int result = 0, i ;
// 创建表
result = InitList(&L);
printf("创建表:%d ,表长度 :%d\n\n", result, L.length);
// 初始化表数据
for(i = 0; i < LIST_ININ_SIZE ; i++){
result = insertList_sq(&L, i+1, i+1);
printf("初始化数据表:%d ,表长度 :%d\n", result, L.length);
printf("表数据:%d \n", L.elem[i]);
}
printf("\n");
// 新增表数据
result = insertList_sq(&L, 6, 6);
printf("插入表:%d ,表长度 :%d\n", result, L.length);
printf("表数据:%d\n\n", L.elem[i]);
//删除一个数据
result = delList_index(&L, 2);
printf("删除表:%d ,表长度:%d\n\n", result, L.length);
//二分查找数据
result = binary_search(&L, 2);
return 0;
}