顺序表的实现

这篇文章我们来整理下与顺序表有关的内容

首先说明一下顺序表的概念:
        顺序表是计算机在内存中以数组形式保存的一种线性表,它用一组地址连续的存储单元依次存储数据元素的线性结构。它是一种最简单的数据结构,除了线性表中的第一个和最后一个元素之外,其他元素都是以直线首尾相接。

顺序表详解

一、定义顺序表中的结构体:

typedef struct SeqList
{
	DataType array[MaxSize];
	int size;   // 有效数据元素的个数
}SeqList, *pSeqlist;
        如上代码所示,我们定义了一个结构体,存放了顺序表中的内容与有效元素的个数,同时我们又对结构体重新定义了结构体指针(*pSeqlist)和结构体(Seqlist)

二、实现与结构体有关的函数


顺序表的基本操作

本篇文章主要提供了以下与顺序表有关的函数:

// 初始化顺序表
void InitSeqList(SeqList* seq);
// 在顺序表的尾部插入值为data的元素
void PushBack(SeqList* pSeq, DataType _data);
// 删除顺序表的最后一个元素
void PopBack(SeqList* pSeq);
// 在顺序表的头部插入值为data的元素
void PushFront(SeqList* pSeq, DataType data);
// 删除顺序表头部元素
void PopFront(SeqList* pSeq);
// 在顺序表中pos位置上插入值为data的元素
void Insert(SeqList* pSeq, size_t pos, DataType data);
// 删除顺序表中pos位置上的元素
void Erase(SeqList* pSeq, size_t pos);
// 在顺序表中查找值为data的元素,找到返回该元素的位置,否则返回-1
int Find(SeqList* pSeq, DataType data);
// 删除顺序表中第一个值为data的元素
void Remove(SeqList* pSeq, DataType data);
// 删除顺序表中所有值为data的元素
void RemoveAll(SeqList* pSeq, DataType data);
// 使用冒泡排序给顺序表中的元素排序
void BubbleSort(SeqList* pSeq);
// 使用选择排序给顺序表中的元素排序
void SelectSort(SeqList* pSeq);
// 使用二分查找在顺序表中查找值为data
void BinarySearch(SeqList* pSeq, DataType data);
//打印顺序表
void PrintSeq(SeqList* pSeq);


2.1初始化顺序表

void InitSeqList(SeqList* pseq)
{
	assert(pseq);
	pseq->size = 0;
	memset(pseq, 0, sizeof(pseq)*MaxSize);
	printf("初始化完成!\n");
}

memset定义了一段空间,同时要引入#include <memory.h>头文件。

2.2在顺序表的尾部插入值为data的元素

void PushBack(SeqList* pSeq, DataType _data)
{
	assert(pSeq);
	assert(_data);
	if (pSeq->size == MaxSize)
	{
		printf("此链表已满,不可插入!\n");
		exit(EXIT_FAILURE);
		//EXIT_FAILURE 可以作为exit()的参数来使用,表示没有成功地执行一个程序。
		//EXIT_SUCCESS 作为exit()的参数来使用,表示成功地执行一个程序。
		//stdlib.h
	}
	pSeq->array[pSeq->size] = _data;
	pSeq->size ++;
	printf("插入成功!\n");
}

        在此处用了exit()函数,EXIT_FAILURE 可以作为exit()的参数来使用,表示没有成功地执行一个程序。EXIT_SUCCESS 作为exit()的参数来使用,表示成功地执行一个程序。同时引用头文件stdlib.h。


2.3删除顺序表的最后一个元素

void PopBack(SeqList* pSeq)
{
	assert(pSeq);
	if (pSeq->size == 0)
	{
		printf("此链表已经为空不可删除!\n");
		exit(EXIT_FAILURE);
	}
	pSeq->size--;
	printf("链表删除成功!\n");
}

此处删除前需要判断链表是否为空,如果空则无法删除!

2.4在顺序表的头部插入值为data的元素

void PushFront(SeqList* pSeq, DataType data)
{
	int i = 0;
	assert(pSeq);
	assert(data);
	if (pSeq->size == MaxSize)
	{
		printf("此链表已满,不可插入!\n");
		exit(EXIT_FAILURE);
	}
	pSeq->size++;
	for (i = 1; i <= pSeq->size; i++)
	{
		pSeq->array[pSeq->size] = pSeq->array[pSeq->size - 1];
	}
	pSeq->array[0] = data;
	printf("头插成功!\n");
}

此处需要判断链表是否已满,当链表满了,则无法插入。

2.5 删除顺序表头部元素

void PopFront(SeqList* pSeq)
{
	assert(pSeq);
	int i = 0;
	if (pSeq->size == 0)
	{
		printf("链表为空,无法删除!\n");
		exit(EXIT_FAILURE);
	}
	for (i = 1; i <= pSeq->size ; i++)
	{
		pSeq->array[i-1] = pSeq->array[i];
	}
	pSeq->size--;
	printf("头删完成!\n");
}

2.6在顺序表中pos位置上插入值为data的元素

void Insert(SeqList* pSeq, size_t pos, DataType data)
{
	assert(pSeq);
	assert(pos);
	assert(data);
	size_t i = 0;
	int j = 0;
	/*if (pos > pSeq->size)
	{
		printf("输入位置有错误!\n");
		exit(EXIT_FAILURE);
	}*/
	if (pSeq->size == MaxSize || pos == MaxSize)
	{
		printf("顺序表已满或者插入位置不合理\n");
		exit(EXIT_FAILURE);
	}
	for (i = pSeq->size - 1; i >= pos; i++)
	{
		pSeq->array[i + 1] = pSeq->array[i];
	}
	pSeq->array[pos] = data;
	pSeq->size++;
	printf("插入成功!\n");
}

2.7删除顺序表中pos位置上的元素

void Erase(SeqList* pSeq, size_t pos)
{
	size_t i = 0;
	assert(pSeq);
	assert(pos);
	/*if (pos > pSeq->size)
	{
		printf("输入有误!\n");
		exit(EXIT_FAILURE);
	}*/
	for (i = pSeq->size; i >= pos; i--)
	{
		pSeq->array[i + 1] = pSeq->array[i];
	}
	pSeq->size--;
	printf("删除成功!\n");
}

2.8在顺序表中查找值为data的元素,找到返回该元素的位置,否则返回-1

int Find(SeqList* pSeq, DataType data)
{
	int i = 0;
	assert(pSeq);
	assert(data);
	for (i = 1; i < pSeq->size; i++)
	{
		if (pSeq->array[i] == data)
			return i;
	}
	return -1;
}

2.9删除顺序表中第一个值为data的元素

void Remove(SeqList* pSeq, DataType data)
{
	assert(pSeq);
	assert(data);
	if (pSeq->size == 0)
	{
		printf("顺序表已空,不可删除");
		exit(EXIT_FAILURE);
	}
	int i = 0;
	int j = 0;
	for (i = 0; i < pSeq->size; i++)
	{
		if (pSeq->array[i] == data)
		break;
	}
	if (i == pSeq->size)
	{
		printf("要删除的元素不存在\n");
		exit(EXIT_FAILURE);
	}
	for (j = i + 1; j < pSeq->size; j++)
	{
		pSeq->array[j - 1] = pSeq->array[j];
	}
	pSeq->size--;
	printf("删除成功!\n");
}

2.10删除顺序表中所有值为data的元素

void RemoveAll(SeqList* pSeq, DataType data) 
{
	int count = 0;
	assert(pSeq);
	assert(data);
	if (pSeq->size == 0)
	{
		printf("顺序表已空,不可删除");
		exit(EXIT_FAILURE);
	}
	int i = 0;
	int j = pSeq->size - 1;
	while (i < pSeq->size)
	{
		if (pSeq->array[i] == data)
		{
			while (pSeq->array[j] == data)
			{
				j--;
			}
			pSeq->array[i] = pSeq->array[j];
			count++;
		}
		i++;
	}
	pSeq->size -= count;
	printf("删除成功!\n");
}

2.11使用冒泡排序给顺序表中的元素排序

void BubbleSort(SeqList* pSeq)
{
	int i = 0;
	int j = 0;
	int temp = 0;
	int flag = 1;
	assert(pSeq);
	if (pSeq->size == 0)
	{
		printf("链表为空,无法排序!\n");
		exit(EXIT_FAILURE);
	}
	for (i = 1; i < pSeq->size; i++)
	{
		flag = 1;
		for (j = 0; j < pSeq->size - 1; j++)
		{
			if (pSeq->array[j]>pSeq->array[j + 1])
			{
				temp = pSeq->array[j];
				pSeq->array[j] = pSeq->array[j + 1];
				pSeq->array[j + 1] = temp;
				flag = 0;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
	printf("排序成功!\n");
	
}

2.12使用选择排序给顺序表中的元素排序

void SelectSort(SeqList* pSeq)
{
	assert(pSeq);
	int i = 0;
	int j = 0;
	if (pSeq->size == 0)
	{
		printf("链表为空,无法排序!\n");
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < pSeq->size-1; i++)
	{
		int min_index = i;
		for (j = i + 1; j < pSeq->size; j++)
		{
			if (pSeq->array[j] < pSeq->array[min_index])
			{
				min_index = j;
			}
		}
		if (i != min_index)
		{
			int temp = pSeq->array[i];
			pSeq->array[i] = pSeq->array[min_index];
			pSeq->array[min_index] = temp;
		}
	}
	printf("排序成功!\n");
}

2.13使用二分查找在顺序表中查找值为data

void BinarySearch(SeqList* pSeq, DataType data)
{
	assert(pSeq);
	if (0 == pSeq->size)
	{
		printf("链表为空,无法查找\n");
		exit(EXIT_FAILURE);
	}
	SelectSort(pSeq);
	int left = 0;
	int right = pSeq->size - 1;
	int middle = 0;
	while (left < right)
	{
		middle = (left + right) / 2;
		if (data == pSeq->array[middle])
		{
			printf("找到了\n");
			return;
		}
		else if (data < pSeq->array[middle])
		{
			right = middle - 1;
		}
		else
		{
			left = middle + 1;
		}
	}
	printf("没有找到\n");
}

2.14打印顺序表

void PrintSeq(SeqList* pSeq)
{
	assert(pSeq);
	int i = 0;
	printf("顺序表中的元素有:\n");
	for (i = 0; i < pSeq->size; i++)
	{
		printf("%d ", pSeq->array[i]);
	}
	printf("\n");
}


三、顺序表需要注意的地方

(1)删除之前必须对顺序表是否为空进行检查,如果为空则不可删除。

(2)插入之前必须对顺序表是否满进行检查,如果已满,则不可插入。

(3)因为折半查找是需要有序,所以用折半查找之前必须对元素排序。

四、顺序表的源代码

1、头文件seqlist.h

ifndef __seqlist_h__
#define __seqlist_h__
#pragma warning(disable:4996) 
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <memory.h>
typedef int DataType;
#define MaxSize 2

typedef struct SeqList
{
	DataType array[MaxSize];
	int size;   // 有效数据元素的个数
}SeqList, *pSeqlist;


// 初始化顺序表
void InitSeqList(SeqList* seq);
// 在顺序表的尾部插入值为data的元素
void PushBack(SeqList* pSeq, DataType _data);
// 删除顺序表的最后一个元素
void PopBack(SeqList* pSeq);
// 在顺序表的头部插入值为data的元素
void PushFront(SeqList* pSeq, DataType data);
// 删除顺序表头部元素
void PopFront(SeqList* pSeq);
// 在顺序表中pos位置上插入值为data的元素
void Insert(SeqList* pSeq, size_t pos, DataType data);
// 删除顺序表中pos位置上的元素
void Erase(SeqList* pSeq, size_t pos);
// 在顺序表中查找值为data的元素,找到返回该元素的位置,否则返回-1
int Find(SeqList* pSeq, DataType data);
// 删除顺序表中第一个值为data的元素
void Remove(SeqList* pSeq, DataType data);
// 删除顺序表中所有值为data的元素
void RemoveAll(SeqList* pSeq, DataType data);
// 使用冒泡排序给顺序表中的元素排序
void BubbleSort(SeqList* pSeq);
// 使用选择排序给顺序表中的元素排序
void SelectSort(SeqList* pSeq);
// 使用二分查找在顺序表中查找值为data
void BinarySearch(SeqList* pSeq, DataType data);
//打印顺序表
void PrintSeq(SeqList* pSeq);

void menu();

#endif

2、具体函数实现seqlist.c

#include "seqlist.h"
void menu()
{
	printf("**********************************************\n");
	printf("******    1. 初始化顺序表                *****\n");
	printf("******    2. 头部插入元素                *****\n");
	printf("******    3. 尾部插入元素                *****\n");
	printf("******    4. 删除头部元素                *****\n");
	printf("******    5. 删除最后元素                *****\n");
	printf("******    6. pos位置上插入值元素         *****\n");
	printf("******    7. 删除pos位置上的元素         *****\n");
	printf("******    8. 查找元素                    *****\n");
	printf("******    9. 删除第一个值为data的元素    *****\n");
	printf("******    10.删除所有值为data的元素      *****\n");
	printf("******    11.冒泡排序                    *****\n");
	printf("******    12.选择排序                    *****\n");
	printf("******    13.二分查找                    *****\n");
	printf("******    14.打印顺序链表                *****\n");
	printf("******    0. 退出程序                    *****\n");
	printf("**********************************************\n");
}
void InitSeqList(SeqList* pseq)
{
	assert(pseq);
	pseq->size = 0;
	memset(pseq, 0, sizeof(pseq)*MaxSize);
	printf("初始化完成!\n");
}
void PushBack(SeqList* pSeq, DataType _data)
{
	assert(pSeq);
	assert(_data);
	if (pSeq->size == MaxSize)
	{
		printf("此链表已满,不可插入!\n");
		exit(EXIT_FAILURE);
		//EXIT_FAILURE 可以作为exit()的参数来使用,表示没有成功地执行一个程序。
		//EXIT_SUCCESS 作为exit()的参数来使用,表示成功地执行一个程序。
		//stdlib.h
	}
	pSeq->array[pSeq->size] = _data;
	pSeq->size ++;
	printf("插入成功!\n");
}
void PopBack(SeqList* pSeq)
{
	assert(pSeq);
	if (pSeq->size == 0)
	{
		printf("此链表已经为空不可删除!\n");
		exit(EXIT_FAILURE);
	}
	pSeq->size--;
	printf("链表删除成功!\n");
}
void PushFront(SeqList* pSeq, DataType data)
{
	int i = 0;
	assert(pSeq);
	assert(data);
	if (pSeq->size == MaxSize)
	{
		printf("此链表已满,不可插入!\n");
		exit(EXIT_FAILURE);
	}
	pSeq->size++;
	for (i = 1; i <= pSeq->size; i++)
	{
		pSeq->array[pSeq->size] = pSeq->array[pSeq->size - 1];
	}
	pSeq->array[0] = data;
	printf("头插成功!\n");
}
void PopFront(SeqList* pSeq)
{
	assert(pSeq);
	int i = 0;
	if (pSeq->size == 0)
	{
		printf("链表为空,无法删除!\n");
		exit(EXIT_FAILURE);
	}
	for (i = 1; i <= pSeq->size ; i++)
	{
		pSeq->array[i-1] = pSeq->array[i];
	}
	pSeq->size--;
	printf("头删完成!\n");
}
void Insert(SeqList* pSeq, size_t pos, DataType data)
{
	assert(pSeq);
	assert(pos);
	assert(data);
	size_t i = 0;
	int j = 0;
	/*if (pos > pSeq->size)
	{
		printf("输入位置有错误!\n");
		exit(EXIT_FAILURE);
	}*/
	if (pSeq->size == MaxSize || pos == MaxSize)
	{
		printf("顺序表已满或者插入位置不合理\n");
		exit(EXIT_FAILURE);
	}
	for (i = pSeq->size - 1; i >= pos; i++)
	{
		pSeq->array[i + 1] = pSeq->array[i];
	}
	pSeq->array[pos] = data;
	pSeq->size++;
	printf("插入成功!\n");
}
void Erase(SeqList* pSeq, size_t pos)
{
	size_t i = 0;
	assert(pSeq);
	assert(pos);
	/*if (pos > pSeq->size)
	{
		printf("输入有误!\n");
		exit(EXIT_FAILURE);
	}*/
	for (i = pSeq->size; i >= pos; i--)
	{
		pSeq->array[i + 1] = pSeq->array[i];
	}
	pSeq->size--;
	printf("删除成功!\n");
}
int Find(SeqList* pSeq, DataType data)
{
	int i = 0;
	assert(pSeq);
	assert(data);
	for (i = 1; i < pSeq->size; i++)
	{
		if (pSeq->array[i] == data)
			return i;
	}
	return -1;
}
void Remove(SeqList* pSeq, DataType data)
{
	assert(pSeq);
	assert(data);
	if (pSeq->size == 0)
	{
		printf("顺序表已空,不可删除");
		exit(EXIT_FAILURE);
	}
	int i = 0;
	int j = 0;
	for (i = 0; i < pSeq->size; i++)
	{
		if (pSeq->array[i] == data)
		break;
	}
	if (i == pSeq->size)
	{
		printf("要删除的元素不存在\n");
		exit(EXIT_FAILURE);
	}
	for (j = i + 1; j < pSeq->size; j++)
	{
		pSeq->array[j - 1] = pSeq->array[j];
	}
	pSeq->size--;
	printf("删除成功!\n");
}
void RemoveAll(SeqList* pSeq, DataType data) 
{
	int count = 0;
	assert(pSeq);
	assert(data);
	if (pSeq->size == 0)
	{
		printf("顺序表已空,不可删除");
		exit(EXIT_FAILURE);
	}
	int i = 0;
	int j = pSeq->size - 1;
	while (i < pSeq->size)
	{
		if (pSeq->array[i] == data)
		{
			while (pSeq->array[j] == data)
			{
				j--;
			}
			pSeq->array[i] = pSeq->array[j];
			count++;
		}
		i++;
	}
	pSeq->size -= count;
	printf("删除成功!\n");
}
void BubbleSort(SeqList* pSeq)
{
	int i = 0;
	int j = 0;
	int temp = 0;
	int flag = 1;
	assert(pSeq);
	if (pSeq->size == 0)
	{
		printf("链表为空,无法排序!\n");
		exit(EXIT_FAILURE);
	}
	for (i = 1; i < pSeq->size; i++)
	{
		flag = 1;
		for (j = 0; j < pSeq->size - 1; j++)
		{
			if (pSeq->array[j]>pSeq->array[j + 1])
			{
				temp = pSeq->array[j];
				pSeq->array[j] = pSeq->array[j + 1];
				pSeq->array[j + 1] = temp;
				flag = 0;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
	printf("排序成功!\n");
	
}
void SelectSort(SeqList* pSeq)
{
	assert(pSeq);
	int i = 0;
	int j = 0;
	if (pSeq->size == 0)
	{
		printf("链表为空,无法排序!\n");
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < pSeq->size-1; i++)
	{
		int min_index = i;
		for (j = i + 1; j < pSeq->size; j++)
		{
			if (pSeq->array[j] < pSeq->array[min_index])
			{
				min_index = j;
			}
		}
		if (i != min_index)
		{
			int temp = pSeq->array[i];
			pSeq->array[i] = pSeq->array[min_index];
			pSeq->array[min_index] = temp;
		}
	}
	printf("排序成功!\n");
}
void BinarySearch(SeqList* pSeq, DataType data)
{
	assert(pSeq);
	if (0 == pSeq->size)
	{
		printf("链表为空,无法查找\n");
		exit(EXIT_FAILURE);
	}
	SelectSort(pSeq);
	int left = 0;
	int right = pSeq->size - 1;
	int middle = 0;
	while (left < right)
	{
		middle = (left + right) / 2;
		if (data == pSeq->array[middle])
		{
			printf("找到了\n");
			return;
		}
		else if (data < pSeq->array[middle])
		{
			right = middle - 1;
		}
		else
		{
			left = middle + 1;
		}
	}
	printf("没有找到\n");
}
void PrintSeq(SeqList* pSeq)
{
	assert(pSeq);
	int i = 0;
	printf("顺序表中的元素有:\n");
	for (i = 0; i < pSeq->size; i++)
	{
		printf("%d ", pSeq->array[i]);
	}
	printf("\n");
}

3、测试函数test.c

#include "seqlist.h"
int main()
{
	SeqList	seq;
	pSeqlist pSeq = &seq;
	int x = 0;
	int i = 1;
	int pos = 0;
	int ret = 0;
	while (i)
	{
		menu();
		printf("请输入相应序号:");
		scanf("%d", &i);
		switch (i)
		{
		case 1:
			InitSeqList(pSeq);
			break;
		case 2:
			printf("请输入要插入的数字:");
			scanf("%d", &x);
			PushFront(pSeq, x);
			break;
		case 3:
			printf("请输入需要插入的数字:");
			scanf("%d", &x);
			PushBack(pSeq,  x);
			break;
		case 4:
			PopFront(pSeq);
			break;
		case 5:
			PopBack(pSeq);
			break;
		case 6:
			printf("请输入插入位置:");
			scanf("%d", &pos);
			printf("\n");
			printf("请输入插入数字:");
			scanf("%d", &x);
			printf("\n");
			Insert(pSeq, pos, x);
			break;
		case 7:
			Erase(pSeq, pos);
			break;
		case 8:
			printf("请输入查找元素:");
			scanf("%d", &pos);
			ret=Find(pSeq, x);
			if (ret != -1)
			{
				printf("找到了!\n");
			}
			printf("没找到!\n");
			break;
		case 9:
			printf("请输入需要删除的数字:");
			scanf("%d", &x);
			Remove(pSeq, x);
			break;
		case 10:
			printf("请输入需要删除的数字:");
			scanf("%d", &x);
			RemoveAll(pSeq, x);
			break;
		case 11:
			BubbleSort(pSeq);
			break;
		case 12:
			SelectSort(pSeq);
			break;
		case 13:
			printf("请输入查找元素:");
			scanf("%d", &x);
			BinarySearch(pSeq, x);
			break;
		case 14:
			break;
		default:
			break;
		}	
	}
	system("pause");
	return 0;
}

五、顺序表的实现效果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值