顺序表一系列操作

在顺序表中,每个结点的存储地址是该结点在表中的位置的线性函数,是一种随机存取结构。顺序表是用向量实现的线性表,向量的下标可以看作结点的相对地址。因此顺序表的的特点是逻辑上相邻的结点其物理位置亦相邻。下面对顺序表进行头插、头删、尾插、尾删、指定位置插入数据、查找数据位置、删除某一个数、折半查找、冒泡排序和选择排序等操作并进行测试。

头函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define MAX_SIZE 100
typedef int DataType;

typedef struct SeqList
{
	DataType arry[MAX_SIZE];
	size_t size;
}SeqList;

各函数的编写:

#include"SeqList.h"

void PrintSeqList(SeqList* pSeq)
{
	assert(pSeq);
	if (pSeq->size > 0 && pSeq->size <= MAX_SIZE)
	{
		for (int begin = 0; begin < (int)pSeq->size; begin++)
		{
			printf("%d ", pSeq->arry[begin]);
		}
	}
	else
	{
		printf("SeqList is Empty!");
		return;
	}
}
void InitSeqList(SeqList* pSeq)
{
	assert(pSeq);
	pSeq->size = 0;
	for (int begin = 0; begin < (int)pSeq->size; begin++)
	{
		pSeq->arry[begin] = 0;
	}
}
void PushBack(SeqList* pSeq, DataType x)//尾插
{
	assert(pSeq);
	if (pSeq->size >= MAX_SIZE)
	{
		printf("SeqList is Full!");
		return;
	}
	else
	{
		pSeq->arry[pSeq->size] = x;
        ++pSeq->size;
	}
}
void PopBack(SeqList* pSeq)//尾删
{
	assert(pSeq);
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	else
	{
		pSeq->arry[pSeq->size] = 0;
		--pSeq->size;
	}
}
void PushFront(SeqList* pSeq, DataType x)//头插
{
	assert(pSeq);
	if (pSeq->size >= MAX_SIZE)
	{
		printf("SeqList is Full!");
		return;
	}
	else
	{
		for (int i = pSeq->size; i > 0; i--)
		{//第一位数以后的数从后往前依次后移一位
			pSeq->arry[i] = pSeq->arry[i - 1];
		}
		pSeq->arry[0] = x;//第一位插入x
		++pSeq->size;
	}
}
void PopFront(SeqList* pSeq)//头删
{
	assert(pSeq);
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	else
	{
		for (int i = 0; i < (int)pSeq->size - 1; i++)
		{//第一位以后的数从前向后依次前移一位
			pSeq->arry[i] = pSeq->arry[i + 1];
		}
		--pSeq->size;
	}
}

void Insert(SeqList* pSeq, size_t pos, DataType x)//在指定位置处插入一个数
{
	assert(pSeq);
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	else if (pSeq->size < pos || pos<0)
	{
		printf("Position is not exist!");
		return;
	}
	else
	{
		for (int i = (int)pSeq->size; i > (int)pos - 1; i--)
		{//第pos-1位以后的数从后往前依次后移一位
			pSeq->arry[i] = pSeq->arry[i - 1];
		}
		pSeq->arry[pos - 1] = x;//第pos位插入x
		++pSeq->size;
	}
}
int Find(SeqList* pSeq, DataType x)//查找指定数的位置
{
	assert(pSeq);
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return -1;
	}
	else
	{
		for (int i = 0; i < (int)pSeq->size; i++)
		{
			if (pSeq->arry[i] == x)
				return i + 1;
		}
		printf("x is not exist!");
		return -1;
	}
}
void Erase(SeqList* pSeq, size_t pos)//删除某位的值
{
	assert(pSeq);
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	else if (pSeq->size < pos || pos<0)
	{
		printf("Position is not exist!");
		return;
	}
	else
	{
		for (int i = (int)pos - 1; i < (int)pSeq->size - 1; i++)
		{//第pos位以后的数从前向后依次前移一位
			pSeq->arry[i] = pSeq->arry[i + 1];
		}
		--pSeq->size;
	}
}
void Remove(SeqList* pSeq, DataType x)//删除某数
{
	assert(pSeq);
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	int pos = Find(pSeq, x);
	Erase(pSeq, pos);
}
void RemoveAll(SeqList* pSeq, DataType x)//删除所有x
{
	assert(pSeq);
	int count = 0;
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	for (int i = 0; i < (int)pSeq->size; i++)
	{
		//1 2 3 4 3 5 3
		//如果删除所有3,当遇到一个3时,count++;其后面的数依次前移count位
		if (pSeq->arry[i] == x)
			count++;
		else
			pSeq->arry[i - count] = pSeq->arry[i];
	}
	pSeq->size -= count;
}

void swap(int* num1, int* num2)
{
	assert(num1);
	assert(num2);
	int temp = *num1;
	*num1 = *num2;
	*num2 = temp;
}
void BubbleSort(SeqList* pSeq)//冒泡排序
{
	assert(pSeq);
	int flag;//冒泡排序的优化:定义一个标志位flag,接近有序时停止冒泡
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	for (int j = 0; j < (int)pSeq->size - 1; j++)//排序pSeq->size - 1趟
	{
		for (int i = 0; i < (int)pSeq->size - j - 1; i++)//每一趟冒泡出一个最大数
		{
			flag = 0;
			if (pSeq->arry[i] > pSeq->arry[i + 1])
			{
				flag = 1;
				swap(&pSeq->arry[i], &pSeq->arry[i + 1]);
			}
			if (flag = 0)
				return;
		}
	}
}
//选择排序的优化:一次选出最大最小的数据分别放在序列的两端
void SeclectSort(SeqList* pSeq)
{
	assert(pSeq);
	int i, j, min, max;
	int len = pSeq->size - 1;
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return;
	}
	for (i = 0; i < (int)pSeq->size - 1; i++, len--)
	{
		min = 0;
		max = len;
		for (j = i; j <= max; j++)
		{//比较第i个元素和其后的元素找到最小的和最大的
			if (pSeq->arry[j] < pSeq->arry[min])
				swap(&pSeq->arry[j], &pSeq->arry[min]);
			if (pSeq->arry[j] > pSeq->arry[max])
				swap(&pSeq->arry[j], &pSeq->arry[max]);
		}
	}

}

int BinarySearch(SeqList* pSeq, DataType x)//折半查找
{
	assert(pSeq);
	int left = 0;
	int right = pSeq->size;//此法为左闭右开区间
	//int right = pSeq->size - 1;此法为左闭右闭区间
	if (pSeq->size <= 0)
	{
		printf("SeqList is Empty!");
		return -1;
	}
	while (left < right)
	//while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (pSeq->arry[mid] < x)
			left = mid + 1;
		else if (pSeq->arry[mid] > x)
			right = mid;
		//right = mid - 1;
		else
			return mid + 1;
	}
	return -1;
}

主函数中对各函数进行测试用例:

#include"SeqList.h"

void PrintSeqList(SeqList* pSeq);
void InitSeqList(SeqList* pSeq);
void PushBack(SeqList* pSeq, DataType x);
void PopBack(SeqList* pSeq);
void PushFront(SeqList* pSeq, DataType x);
void PopFront(SeqList* pSeq);

void Insert(SeqList* pSeq, size_t pos, DataType x);
int Find(SeqList* pSeq,DataType x);
void Erase(SeqList* pSeq, size_t pos);//删除某位的值
void Remove(SeqList* pSeq, DataType x);//删除某数
void RemoveAll(SeqList* pSeq, DataType x);//删除所有x

void BubbleSort(SeqList* pSeq);
//冒泡排序的优化:一次选出最大最小的数据分别放在序列的两端
void SeclectSort(SeqList* pSeq);
int BinarySearch(SeqList* pSeq, DataType x);

void Test1()
{//尾插尾删
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PrintSeqList(&seq);
	PopBack(&seq);
	PopBack(&seq);
	printf("\n---------------\n");
	PrintSeqList(&seq);
	PopBack(&seq);
	PopBack(&seq);
	printf("\n---------------\n");
	PopBack(&seq);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test2()
{//头插头删
	SeqList seq;
	InitSeqList(&seq);
	PushFront(&seq, 1);
	PushFront(&seq, 2);
	PushFront(&seq, 3);
	PushFront(&seq, 4);
	PrintSeqList(&seq);
	PopFront(&seq);
	PopFront(&seq);
	printf("\n---------------\n");
	PrintSeqList(&seq);
	PopFront(&seq);
	PopFront(&seq);
	printf("\n---------------\n");
	PopFront(&seq);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test3()
{//在指定位置处插入一个数
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 1);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PushBack(&seq, 5);
	PrintSeqList(&seq);
	Insert(&seq, 2, 2);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test4()
{//查找指定数的位置
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PrintSeqList(&seq); 
	printf("\n---------------\n");
	printf("%d\n",Find(&seq, 2));
}

void Test5()
{//删除某位的值
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PrintSeqList(&seq);
	Erase(&seq, 3);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test6()
{//删除某数
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PrintSeqList(&seq);
	Remove(&seq, 2);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test7()
{//删除所有指定的数
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PushBack(&seq, 3);
	PushBack(&seq, 5);
	PushBack(&seq, 3);
	PrintSeqList(&seq);
	RemoveAll(&seq, 3);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test8()
{//冒泡排序
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 8);
	PushBack(&seq, 7);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PushBack(&seq, 6);
	PushBack(&seq, 5);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PrintSeqList(&seq);
	BubbleSort(&seq);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test9()
{//选择排序
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 8);
	PushBack(&seq, 7);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PushBack(&seq, 6);
	PushBack(&seq, 5);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PrintSeqList(&seq);
	SeclectSort(&seq);
	printf("\n---------------\n");
	PrintSeqList(&seq);
}

void Test10()
{//折半查找
	SeqList seq;
	InitSeqList(&seq);
	PushBack(&seq, 0);
	PushBack(&seq, 1);
	PushBack(&seq, 2);
	PushBack(&seq, 3);
	PushBack(&seq, 4);
	PrintSeqList(&seq);
	printf("\n---------------\n");
	printf("%d is position %d\n", 3, BinarySearch(&seq, 3));
}

int main()
{
	Test1();
	printf("\n*********************\n");
	Test2();
	printf("\n*********************\n");
	Test3();
	printf("\n*********************\n");
	Test4();
	printf("\n*********************\n");
	Test5();
	printf("\n*********************\n");
	Test6();
	printf("\n*********************\n");
	Test7();
	printf("\n*********************\n");
	Test8();
	printf("\n*********************\n");
	Test9();
	printf("\n*********************\n");
	Test10();
	system("pause");
}

小知识:

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

可以采用两种方式(如上述程序中所示):

方法一,采用[]闭区间的方式。

方法二,采用[ )左闭右开的方式。

时间: 2024-10-22 20:39:16

顺序表一系列操作的相关文章

顺序表 其他操作

1 实验2 顺序表其它操作 2 实验目的 3 1.进一步掌握在线性表的顺序存储结构上的一些其它操作. 4 实验内容 5 程序1 6 已知一个线性表,用另辟空间和利用原表两种方法把线性表逆置. 7 设计要求:在程序中构造三个子程序分别为 8 SeqList reverse(SeqList A) /*顺序表的就地逆置 */ 9 void ListTraverse(SeqList L) /* 遍历顺序表 */ 10 SeqList create(int n) /* 建立顺序表 */ 11 12 程序2

07、顺序表的操作

顺序表的操作 一.从顺序表中删除具有最小值的元素 /* 时间:2017年7月2日10:49:39 功能:从顺序表中删除具有最小值的元素并将最后元素放于被删除元素的位置,由函数返回被删元素的值 */ #include "stdio.h" #include "string.h" #include"stdlib.h" #define maxSize 15 //显式地定义表的长度 typedef int DataType; //定义表元素的数据类型 ty

Java 3:顺序表的操作

顺序表常见操作有插入.删除.查找.修改.一.插入:1.插入有头插.尾插.任意位置插入.在插入时要注意下标的取值在顺序表长度范围内.所以最好在插入之前进行扩容操作.2.在头插时要注意先将原数组的元素从后往前依次向后移动.因为如果从前往后开始移动的话,会造成后一个元素被前一个元素覆盖,而丢失数据且造成重复.arr[i+1]=arr[i],注意此处i的意思是要移动的元素的下标.3.任意位置插入与头插类似,从后往前(要插入的位置元素下标)依次向后移动,再将数据插入二.删除1.删除有头删.尾删.任意位置删

数据结构顺序表的操作全集(创建,遍历,插入,删除,排序等等)

#include"stdio.h" #include"stdlib.h" #include"malloc.h" #define list_size 100 typedef struct Node { int data[list_size]; int len; }NODE,* PNODE; void creat_list(PNODE L) { int i; int val; int len; /* PNODE L=(PNODE)malloc(siz

一个简单的顺序表基础操作示例

最近学计算机软件基础,学到了线性表.下面就将线性表中最简单的顺序表的一个简单示例贴出,方便大家探讨.(以及后面对函数传参的一个小分析,其实这才是重点) 1 ////需求分析 2 //1.线性表递增有序,删除重复元素 3 //2.线性表逆置 4 //3.寻求最大值 5 6 #include<stdio.h> 7 8 typedef int ElementType; 9 typedef struct _struct 10 { 11 ElementType SequenceList[100]; 12

数据结构——顺序表及其操作

今天总结了一下顺序表的一些操作实现,算是这个本该上而没有上的体育课的一些小收获吧! BTW,青轴用起来是爽,但时间长了感觉自己的手指痛的不行呀/TOT/~~ 1 #include<iostream> 2 3 using namespace std; 4 5 #define MAXSIZE 100 //最大长度 6 #define OK 1 7 #define ERROR -1 8 9 10 //类型重命名 11 typedef int Elemtype; 12 typedef int Stat

作业1:顺序表的操作

#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; class Seqlist{ public: int last; int sz; int *data; Seqlist(int _sz=0){ ///构造函数 data = new int[_sz]; last = -1; sz = _sz; } void Insert(int i, int value){ ///插

c数据结构 顺序表和链表 相关操作

编译器:vs2013 内容: #include "stdafx.h"#include<stdio.h>#include<malloc.h>#include<stdlib.h> #define LINK_INIT_SIZE 100#define LISTINCREAMENT 10#define ElemType int#define OVERFLOW -2#define OK 1#define ERROR 0 typedef int status; /

6-2 顺序表操作集

6-2 顺序表操作集(20 分) 本题要求实现顺序表的操作集. 函数接口定义: List MakeEmpty(); Position Find( List L, ElementType X ); bool Insert( List L, ElementType X, Position P ); bool Delete( List L, Position P ); 其中List结构定义如下: typedef int Position; typedef struct LNode *List; str