数据结构1--顺序表

1.数据结构(DS)是什么? 

数据结构是数据之间的组织架构,数据结构的表现形式:顺序表seqlist、链表list、树tree、图graph、排序sort、搜索search;最终目标是为搜索服务,快速准确的查找想要的数据。

2.如何衡量一个算法的好坏?

时间复杂度和空间复杂度

3.数据结构的分类

(1)顺序结构(线性结构也叫线性表)

顺序表 链表 队列 栈

(2)非线性结构(关联结构)

树、图

(3)排序

(4)搜索

4.线性结构特点:除了第一个元素和最后一个元素之外,其与元素必须有且仅有一个前驱和后继


顺序表

注意:头删的时候需要把后面的数据往前移动,注意越界问题; 头插的时候需要把数据往后移动一个,空出位置来

//Common.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <memory.h>
#include <vld.h>
typedef int SLDataType;

void Swap(SLDataType* x, SLDataType* y)
{
	SLDataType temp = *x;
	*x = *y;
	*y = temp;
}
//main.cpp
#include "seqlist.h"
#pragma warning (disable:4996)
int main()
{
	Seqlist list;
	SeqListInit(&list);
	int pos=0;
	int select = 0;
	int item = 0;
	bool flag;
	while (1){
		printf("****************************************\n");
		printf("**  0.exit_system       1.show_list   **\n");
		printf("**  2.push_back         3.pop_back    **\n");
		printf("**  4.push_front        5.pop_front   **\n");
		printf("**  6.insert_pos        7.insert_val  **\n");
		printf("**  8.erase_pos         9.earse_val   **\n");
		printf("**  10.length           11.find       **\n");
		printf("**  12.sort             13.reverse    **\n");
		printf("**  14.front            15.back       **\n");
		printf("**  16.capacity         17.clear      **\n");
		printf("**  18.binary_find                    **\n");//二分查找必须先排序 删除所有(1 2 2 2 3)重复的都删除
		printf("****************************************\n");
		printf("请输入你要选择的选项:");
		scanf("%d",&select);
		if (select == 0)
		{
			printf("系统正在退出,byebye!\n");
			system("pause");
			break;
		}
		switch (select)
		{
		case 1:
			SeqListShow(&list);
			break;
		case 2:
			printf("请输入你要插入的数据<以-1结束>:");
			while (scanf("%d", &item), item != -1)
			{
				SeqListPushBack(&list, item);
			}
			printf("尾部插入数据成功!\n");
			break;
		case 3:
			SeqListPopBack(&list);
			printf("尾部删除数据成功!\n");
			break;
		case 4:
			printf("请输入你要插入的数据<以-1结束>:");
			while (scanf("%d", &item), item != -1)
			{
				SeqListPushFront(&list, item);
			}
			printf("头部插入数据成功!\n");
			break;
		case 5:
			SeqListPopFront(&list);
			printf("头部删除数据成功!\n");
			break;
		case 6:
			printf("请输入要插入的位置:");
			scanf("%d", &pos);
			printf("请输入你要插入的元素:");
			scanf("%d", &item);
			flag=SeqListPush_Pos(&list, pos, item);
			if (flag)
			{
				printf("插入数据成功.......\n");
			}
			else
			{
				printf("插入数据失败.......\n");
			}
			break;
		case 7:
			printf("请输入你要插入的元素:");
			scanf("%d", &item);
			flag=SeqListPush_Val(&list, item);
			if (flag)
			{
				printf("插入数据成功.......\n");
			}
			else
			{
				printf("插入数据失败.......\n");
			}
			break;
		case 8:
			printf("请输入要删除的元素的位置:");
			scanf("%d", &pos);
			SeqListPop_Pos(&list,pos);
			break;
		case 9:
			printf("请输入要删除的元素的值:");
			scanf("%d", &item);
			SeqListPop_Val(&list, item);
			break;
		case 10:
			printf("length=%d\n",SeqListLength(&list));
			break;
		case 11:
			printf("请输入你要查找的元素:");
			scanf("%d", &item);
			pos=SeqList_Find(&list,item);
			if (pos == -1)
			{
				printf("查找失败!\n");
			}
			else {
				printf("查找成功,在%d的位置", pos);
			}
			break;
		case 12:
			SeqListSort(&list);
			printf("顺序表排序成功......\n");
			break;
		case 13:
			SeqListReverse(&list);
			printf("转置完成.\n");
			break;
		case 14:
			printf("表头元素为:%d\n",SeqListFront(&list));
			break;
		case 15:
			printf("表尾元素为:%d\n",SeqListBack(&list));
			break;
		case 16:
			printf("capacity=%d\n", SeqList_Capacity( &list));
			break;
		case 17:
			 SeqListClear(&list);
			break;
		case 18:
			SeqListSort(&list);
			printf("请输入你要查找的元素:");
			scanf("%d", &item);
			pos=SeqList_Find_Binary(& list,item);
			if (pos == -1)
			{
				printf("查找失败!\n");
			}
			else {
				printf("查找成功,在%d的位置", pos);
			}
			break;
		default:
			printf("命令出错,请重新输入......\n");
			break;
		}
		system("pause");
		system("cls");
	}

	return 0;
}
//seqlist.h

#include "Common.h"
#define SEQLIST_SIZE 8


typedef struct Seqlist{
SLDataType* base;//数组
size_t size;//底层大小
size_t capacity;//元素个数
}Seqlist;

//声明
void SeqListInit(Seqlist* list);//初始化
void SeqListPushBack(Seqlist* list,SLDataType x);//尾插
void SeqListPopBack(Seqlist* list);//尾删
void SeqListPushFront(Seqlist* list,SLDataType x);//头插
void SeqListPopFront(Seqlist* list);//头删
bool SeqListPush_Pos(Seqlist* list,int pos,SLDataType x);//按位置插入
void SeqListPop_Pos(Seqlist* list,int pos);//按位置删除
bool SeqListPush_Val(Seqlist* list,SLDataType val);//按值插入
void SeqListPop_Val(Seqlist* list, SLDataType val);//按值删除
void SeqListShow(Seqlist* list);//show
SLDataType SeqListFront(Seqlist* list);//首元素
SLDataType SeqListBack(Seqlist* list);//尾元素
size_t SeqListLength(Seqlist* list);//顺序表的长度
size_t SeqList_Capacity(Seqlist* list);//顺序表的底层大小
void SeqListSort(Seqlist* list);//顺序表的排序
void SeqListReverse(Seqlist* list);//顺序表的逆置
int SeqList_Find(Seqlist* list,SLDataType key);//查找
int SeqList_Find_Binary(Seqlist* list,SLDataType key);//二分查找法
void SeqListClear(Seqlist* list);//顺序表的清空
void SeqListDestroy(Seqlist* list);//销毁顺序表


//实现
bool _Inc(Seqlist* list, size_t new_capacity)
{
	assert(list != NULL&&new_capacity > list->capacity);

	SLDataType* new_base = (SLDataType*)realloc(list->base, sizeof(SLDataType)*new_capacity);
	if (new_capacity == NULL)
	{
		return false;
	}
	list->base = new_base;
	list->capacity = new_capacity;
	return true;
}
bool isFull(Seqlist* list)
{
	return list->capacity == list->size;
}
bool isEmpty(Seqlist* list)
{
	return list->size == 0;//数组为空
}
void SeqListInit(Seqlist* list)
{
	assert(list!=NULL);
	list->capacity = SEQLIST_SIZE;
	list->size = 0;
	//申请空间
	list->base = (SLDataType *)malloc(list->capacity*sizeof(SLDataType));
}
void SeqListPushBack(Seqlist* list, SLDataType x)
{
	assert(list!=NULL);
	//要判断是否满了
	if (isFull(list))
	{
		printf("顺序表已满,不能插入!\n");
		return;
	}
	
	list->base[list->size] = x;
	list->size++;
}
void SeqListPopBack(Seqlist* list)
{
	assert(list!=NULL);
	if (isEmpty(list))
	{
		printf("顺序表为空,不能删除!\n");
		return;
	}
	list->size--;
}
void SeqListPushFront(Seqlist* list, SLDataType x)
{
	assert(list!=NULL);
	size_t i = list->size;//该位置没有元素 这里得注意
	for (; i >0; i--)
	{
		list->base[i] = list->base[i - 1];
	}
	list->base[0] = x;
	list->size++;
}
void SeqListPopFront(Seqlist* list)
{
	assert(list!=NULL);
	//如果为空
	if (isEmpty(list))
	{
		printf("顺序表为空,不能进行删除!\n");
		return;
	}
	size_t i = 0;
	for (; i < list->size; i++)
	{
		list->base[i] = list->base[i + 1];
	}
	list->size--;
}
//按位置插入 
bool SeqListPush_Pos(Seqlist* list,int pos,SLDataType x)
{
	assert(list!=NULL);
	//如果满了或二次空间申请失败  注意只有第一个条件成立时 第二个条件才会执行 
	if (isFull(list) && !_Inc(list,( list->capacity) * 2))
	{
		printf("顺序表已满,%d不能在%d位置插入!\n",x,pos);
		return false;
	}

	//如果要插入的位置超过size 就是不合法的
	if (pos<0 || pos>list->size)
	{
		printf("要插入的位置不合法,%d不能在%d位置插入!\n", x, pos);
		printf("请重新输入!\n");
		return false;
	}
	
    size_t i = list->size;
	for (; i >pos; i--)
	{
		list->base[i] = list->base[i - 1];
	}
	list->base[pos] = x;
	list->size++;

	return true;
}

//按位置删除
void SeqListPop_Pos(Seqlist* list,int pos)
{
	assert(list!=NULL);
	//如果为空
	if (isEmpty(list))
	{
		printf("顺序表为空,不能进行删除!\n");
		return;
	}
	if(pos<0 || pos>list->size)
	{
		printf("要删除的位置不合法,不能删除该位置\n");
		return;
	}
	int i;
	for (i=pos; i < list->size; i++)
	{
		list->base[i] = list->base[i + 1];
	}
	list->size--;
}
//按值插入 
bool SeqListPush_Val(Seqlist* list,SLDataType val)
{
	assert(list!=NULL);
	if (isFull(list)&&!_Inc(list,list->capacity*2))
	{
		printf("顺序列表已满,不能插入!\n");
		return false;
	}
	size_t end = list->size-1 ;
	while (end >= 0 && val < list->base[end])
	{
		list->base[end ] = list->base[end-1];
		end--;
	}
	list->base[end+1] = val;
	list->size++;
	return true;
}
//按值删除
void SeqListPop_Val(Seqlist* list,SLDataType val)
{
	assert(list!=NULL);
	int pos = SeqList_Find(list, val);
	if (pos == -1)//没有找到
	{
		return;
	}
	SeqListPop_Pos(list, pos);
}
void SeqListShow(Seqlist* list)
{
	assert(list);
	if (isEmpty(list))
	{
		printf("顺序表为空,请输入数据!\n");
		return;
	}
	for (size_t i = 0; i < list->size; i++)
	{
		printf("%d ", list->base[i]);
	}
	printf("\n");
}
SLDataType SeqListFront(Seqlist* list)
{
	assert(list != NULL);
	if (isEmpty(list))
	{
		printf("顺序表已空,不能取表头数据.\n");
		return -1;
	}
	return list->base[0];
}
SLDataType SeqListBack(Seqlist* list)
{
	assert(list != NULL);
	if (isEmpty(list))
	{
		printf("顺序表已空,不能取表尾数据.\n");
		return -1;
	}
	return list->base[list->size];
}
size_t SeqListLength(Seqlist* list)
{
	return list->size;
}
size_t SeqList_Capacity(Seqlist* list)
{
	return list->capacity;
}
void SeqListSort(Seqlist* list)
{
	assert(list != NULL);
	size_t i = 0;
	for (; i < list->size-1; ++i)
	{
		size_t j = 0;
		for (; j < list->size - i - 1; ++j)
		{
			if (list->base[j] > list->base[j + 1])
			{
				Swap(&list->base[j], &list->base[j + 1]);
			}
		}
	}

}
int SeqList_Find(Seqlist* list,SLDataType key)
{
	assert(list != NULL);
	int pos = 0;
	while (pos < list->size&&key != list->base[pos])
	{
		pos++;
	}
	//走完 找不到
	if (pos == list->size)
	{
		pos = -1;
	}
	//走完能找到或者走完找不到
	return pos;
}
void SeqListReverse(Seqlist* list)
{
	assert(list!=NULL);
	//边界条件
	if (list->size == 1)
	{
		return;
	}
	int start = 0;
	int end = list->size - 1;
	while (start < end)
	{
		Swap(&list->base[start], &list->base[end]);
		start++;
		end--;
	}
}
int SeqList_Find_Binary(Seqlist* list,SLDataType key)
{
	assert(list != NULL);
	if (isEmpty(list))
	{
		return -1;
	}
	size_t start = 0;
	size_t end = list->size-1;
	size_t mid;
	while (start <= end)
	{
		mid = (start + end) / 2;
		if (key == list->base[mid])
		{
			return mid;
		}
		else if(key>list->base[mid]){
			start = mid + 1;
		}
		else
		{
			end = mid - 1;
		}
	}
	return -1;
}

void SeqListClear(Seqlist* list)
{
	assert(list != NULL);
	list->size = 0;

}
void SeqListDestroy(Seqlist* list)
{
	assert(list != NULL);
	free(list->base);
	list->base = NULL;
	list->capacity = list->size = 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43807876/article/details/115027600