在顺序表中,每个结点的存储地址是该结点在表中的位置的线性函数,是一种随机存取结构。顺序表是用向量实现的线性表,向量的下标可以看作结点的相对地址。因此顺序表的的特点是逻辑上相邻的结点其物理位置亦相邻。下面对顺序表进行头插、头删、尾插、尾删、指定位置插入数据、查找数据位置、删除某一个数、折半查找、冒泡排序和选择排序等操作并进行测试。
头函数:
#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");
}
小知识:
二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
可以采用两种方式(如上述程序中所示):
方法一,采用[]闭区间的方式。
方法二,采用[ )左闭右开的方式。
本文出自 “Scen” 博客,请务必保留此出处http://10741357.blog.51cto.com/10731357/1731042