静态顺序表的实现

程序=数据结构+算法

算法:求解某一个问题的步骤

(1)设计算法的要求:正确性;可读性(最好使用相同含义的英文名作为函数名);健壮性(容错型差:malloc一段空间之后没有释放);时间效率高;空间使用率低(内存空间占的越少越好);简单性

(2)算法的复杂度:

 

a、时间复杂读:不能通过函数运行时间的长短来衡量一个程序的好坏,时间复杂度实际上是一个函数,该函数计算的是执行基本操作的步数。 

 

b、空间复杂度

假设在一组数中查找一个数字,最优情况下,一次就能查找到这个数字;最差情况下,查找元素个数次; 

 

int BinarySearch(int *array, int size, int x)
{
	int left = 0;
	int right = size - 1;//[left,right]
	//int right = size;//[left,right)
	int mid;
	while (left <=right)//while(left<right)
	{
		mid = left + ((right - left) >> 1);
		if (x == array[mid])
			return mid;
		else if (x < array[mid])
		{
			right = mid - 1;//right=mid;
		}
		else
		{
			left = mid + 1;
		}
	}
	return -1;
 }

顺序结构 :连续的空间

静态顺序表:底层的空间已经固定死了

Seqlist.h:

#define MAX_SIZE 10 
typedef unsigned int size_t;
typedef int DataType;
typedef struct SeqList
{
	DataType _array[MAX_SIZE];
	int _size; // 顺序表中有效元素的个数 
}SeqList, *PSeqList;
//typedef struct SeqList SeqList; 
初始化顺序表 
void SeqListInit(PSeqList ps);
尾插 
void SeqListPushBack(PSeqList ps, DataType data);
尾删 
void SeqListPopBack(PSeqList ps);
头插 
void SeqListPushFront(PSeqList ps, DataType data);
头删 
void SeqListPopFront(PSeqList ps);
任意位置中插入值为data的元素 
void SeqListInsert(PSeqList ps, size_t pos, DataType data);
删除任意位置中的元素 
void SeqListErase(PSeqList ps, size_t pos);
在顺序表中查找值为data的元素,返回该元素在顺序表中的下标 
int SeqListFind(PSeqList ps, DataType data);
删除顺序表中值为data的元素 
void SeqListRemove(PSeqList ps, DataType data);
删除顺序表中所有值为data的元素 
void SeqListRemoveAll(PSeqList ps, DataType data);
判断顺序表是否为空 
int SeqListEmpty(PSeqList ps);
获取顺序表中元素的个数 
int SeqListSize(PSeqList ps);
打印顺序表中的元素 
void PrintSeqList(PSeqList ps);
用冒泡排序对顺序表中的元素进行排序 
void BubbleSort(int* array, int size);
用选择排序对顺序表中的元素进行排序 
void SelectSort(int* array, int size);

SeqList.c:

 

# include"Seqlist.h"
void SeqListInit(pSeqlist ps)
{
	if (NULL == ps)
		return;
	ps->size = 0;
	memset(ps->array, 0, sizeof(ps->array));
}
void SeqlistPushBack(pSeqlist ps, DataType data)
{
	if (NULL == ps)
		return;
	if (ps->size == MAX_SIZE)
		return;
	ps->array[ps->size] = data;
	ps->size++;
}
int SeqlistEmpty(pSeqlist ps)
{
	if (NULL == ps)
		return;
	return 0 == ps->size;
}
void SeqlistPopBack(pSeqlist ps, DataType data)
{
	if (SeqlistEmpty(ps))
		return;
	ps->size--;
}
void SeqlistPushFront(pSeqlist ps, DataType data)
{
	int i = 0;
	if (NULL == ps)
		return;
	if (ps->size == MAX_SIZE)
		return;
	for (i = ps->size - 1; i >= 0; --i)
		ps->array[i + 1] = ps->array[i];
	ps->array[0] = data;
	ps->size++;
}
void SeqlistPopFront(pSeqlist ps, DataType data)
{
	int i = 0;
	if (SeqlistEmpty(ps))
		return;
	for (i = 0; i < MAX_SIZE - 1; ++i)
		ps->array[i] = ps->array[i + 1];
	ps->size--;
}
int SeqlistSize(pSeqlist ps)
{
	assert(ps);
	return ps->size;
}
void SeqlistPrint(pSeqlist ps)
{
	int i =0 ;
	assert(ps);
	for (; i < MAX_SIZE - 1; ++i)
	{
		printf("%d", ps->array[i]);
	}
	printf("\n");
}
void SeqlistInsert(pSeqlist ps, size_t pos, DataType data)
{
	int i = 0;
	assert(ps);
	if (MAX_SIZE == ps->size)
	{
		printf("该顺序表满了\n");
		return;
	}
 	if (pos > ps->size)
	{
 		return;
	}
	for (i=ps->size; i > ps->array[pos]; --i)
	{
		ps->array[i] = ps->array[i - 1];
	}
	ps->array[pos] = data;
	ps->size--;
}
void SeqlistErase(pSeqlist ps, size_t pos)
{
	int i = 0;
	if (pos >= ps->size)
		return;
	if (SeqlistEmpty(ps))
		return;
	for (i = pos; i < ps->size; ++i)
	{
		ps->array[i - 1] = ps->array[i];
	}
	ps->size--;
}
int SeqlistFind(pSeqlist ps, DataType data)
{
	int i = 0;
	assert(ps);
	for (; i < ps->size; ++i)
	{
		if (data == ps->array[i])
			return i;
	}
	return -1;
}
//移除第一个值为data的元素
void SeqlistRemove(pSeqlist ps, DataType data)
{
	SeqlistErase(ps, SeqlistFind(ps,data));
}
//移除顺序表中所有值为data的元素:先找到值为data的元素,再删除
void SeqlistRemoveAll(pSeqlist ps, DataType data)
{
 //法1:将不是data的元素放到另外一个数组中,将存放data的那个数组中的元素删除,再将存放除了data之外的其他元素的数组中的元素拷贝回原数组中,
//时间复杂度O(n),空间复杂度也为O(n),用空间换取时间
//法2:我们采用这个方法:使用计数记录下有几个data,个数为count
	int count = 0;
	int i = 0;
	assert(ps);
	for (; i < ps->size; ++i)
	{
		if (ps->array[i] == data)
			count++;
		else
			ps->array[i - count] = ps->array[i];
//把当前i位置的元素搬移到i-count的位置,count为0时,相当于还是自己所在的那个位置,遇到data之后计数加1.
	}

//区间里剩下的元素
	ps->size -= count;
时间复杂度为O(n),空间复杂度O(1)
}
/*法2:
int pos=0;
while(1){
    pos=SeqListFind(ps,data);
    if(pos==-1)
        return;
    Erase(ps,pos);
时间复杂度:查找一个元素为O(n),最差情况找了许多次,为O(n^2)。效果不好。
}*/
/*法3:
while(-1!=(pos=SeqListFind(ps,data)))
{
    Erase(ps,pos);
}
时间复杂度:查找一个元素为O(n),最差情况找了许多次,为O(n^2)。效果不好。
*/

void Swap(int *pleft, int *pRight)
{
	int tmp = *pleft;
	*pleft = *pRight;
	*pRight = tmp;
}
//两个元素的比较,既有升序,又有降序
int Greater(int left,int right)
{
    return left>right;//大则为真
}
int Less(int left,int right)
{
    return left<right;//小则为真
}
//int (*Com)(int left,int right);
//Com:void BubbleSort(int *array, int size)
//此处的Com是一个变量
//用作函数中需要将Com定义为一种类型
typedef int (*Com)(int left,int right);
void BubbleSort(int *array, int size,Com Compare)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < size - 1; ++i)
	{
                int IsChange=0;
		for (j = 0; j < size - i; ++j)
		{
			if (Compare(array[j-1] ,array[j]))
			{
                            Swap(&array[j],&array[j-1];
                            IsChange=1;
		        }			
 		}
                if(!IsChange)//非0是有序的,直接返回
                    return;
	}
}

/*
void BubbleSort(int *array, int size)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < size - 1; ++i)
	{
                int IsChange=0;
		for (j = 0; j < size - i; ++j)
		{
			if (array[j-1] >array[j])
			{
                            Swap(&array[j],&array[j-1];
                            IsChange=1;
		        }			
 		}
                if(!IsChange)//非0是有序的,直接返回
                    return;
	}
}
*/
void SelectSort(int *array, int size)
{
//用maxpos标记目前最大的元素
	int i = 0;
	int j = 0;
	int maxpos = 0;
	for (i = 0; i < size - 1; ++i)
	{
		maxpos = 0;
		for (j = 0; j < size - i; ++j)
		{
			if (array[maxpos] < array[j])
				maxpos = j;
			if (maxpos != size - i - 1)//最大的元素不在应该在的位置上
				Swap(&array[maxpos], &array[size - 1 - i]);
		}
	}
}时间复杂度:查找一个元素为O(n),最差情况找了许多次,为O(n^2)。效果不好。
}*/
/*法3:
while(-1!=(pos=SeqListFind(ps,data)))
{
    Erase(ps,pos);
}
时间复杂度:查找一个元素为O(n),最差情况找了许多次,为O(n^2)。效果不好。
*/

void Swap(int *pleft, int *pRight)
{
	int tmp = *pleft;
	*pleft = *pRight;
	*pRight = tmp;
}
//两个元素的比较,既有升序,又有降序
int Greater(int left,int right)
{
    return left>right;//大则为真
}
int Less(int left,int right)
{
    return left<right;//小则为真
}
//int (*Com)(int left,int right);
//Com:void BubbleSort(int *array, int size)
//此处的Com是一个变量
//用作函数中需要将Com定义为一种类型
typedef int (*Com)(int left,int right);
void BubbleSort(int *array, int size,Com Compare)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < size - 1; ++i)
	{
                int IsChange=0;
		for (j = 0; j < size - i; ++j)
		{
			if (Compare(array[j-1] ,array[j]))
			{
                            Swap(&array[j],&array[j-1];
                            IsChange=1;
		        }			
 		}
                if(!IsChange)//非0是有序的,直接返回
                    return;
	}
}

/*
void BubbleSort(int *array, int size)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < size - 1; ++i)
	{
                int IsChange=0;
		for (j = 0; j < size - i; ++j)
		{
			if (array[j-1] >array[j])
			{
                            Swap(&array[j],&array[j-1];
                            IsChange=1;
		        }			
 		}
                if(!IsChange)//非0是有序的,直接返回
                    return;
	}
}
*/
void SelectSort(int *array, int size)
{
//用maxpos标记目前最大的元素
	int i = 0;
	int j = 0;
	int maxpos = 0;
	for (i = 0; i < size - 1; ++i)
	{
		maxpos = 0;
		for (j = 0; j < size - i; ++j)
		{
			if (array[maxpos] < array[j])
				maxpos = j;
			if (maxpos != size - i - 1)//最大的元素不在应该在的位置上
				Swap(&array[maxpos], &array[size - 1 - i]);
		}
	}
}

 

// 选择排序优化---一次找出最大最小元素所在的位置 

void SelectSortOp(int *array, int size)
{
	int begin = 0;
	int end = 0;
	int maxpos = 0;
	int minpos = 0;
	while(begin<end)
	{
                maxpos=begin;
                minpos=begin;
                int j=begin+1;
                while(j<=end){
		if (array[maxpos] < array[j])
			maxpos = j;
		if (array[minpos]>array[j])
			minpos = j;
                j++;
         }
	if (maxpos != end)//最大的元素没有在最后的位置
		Swap(&array[maxpos], array[end]);
	if (minpos == end)//最小元素出现在最大元素的位置上或者最大元素出现在最小元素的位置上回导致出错
//解决方案:或者标记位一起改变
		minpos = maxpos;
	if (minpos != begin)//最小元素没有在起始位置
		Swap(&array[minpos], &array[begin]);
        begin++;
        end--;
}
//仍然存在缺陷,进行重复性的工作,解决方式:把已经比较过的数据记录下来

底层空间给死了,超过MAX_SIZE上限就不能存放了,用不了这么多空间时又会浪费。

test.c:

# define _CRT_SECURE_NO_WARNNGS
# include"Seqlist.h"
# include<stdio.h>
# include<assert.h>
# include<stdlib.h>
void TestSeqList1()
{
SeqList s;
SeqListInit(&s);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPushBack(&s, 6);
SeqListPushBack(&s, 7);
SeqListPushBack(&s, 8);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListRemove(&s, 6);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListRemove(&s, 6);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListInsert(&s, 5, 6);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListErase(&s, 5);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListPushFront(&s, 0);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListPopFront(&s);
printf("size = %d\n", s._size);
PrintSeqList(&s);


SeqListPopBack(&s);
SeqListPopBack(&s);
printf("size = %d\n", s._size);
PrintSeqList(&s);
}


void TestSeqList2()
{
SeqList s;
SeqListInit(&s);
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 8);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 9);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 7);
SeqListPushBack(&s, 6);


PrintSeqList(&s);


SeqListRemoveAll(&s, 2);
PrintSeqList(&s);
}


void TestSeqList3()
{
SeqList s;
SeqListInit(&s);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPushBack(&s, 7);
SeqListPushBack(&s, 6);
SeqListPushBack(&s, 9);
SeqListPushBack(&s, 0);
SeqListPushBack(&s, 1);
PrintSeqList(&s);


//BubbleSort(s._array, SeqListSize(&s), Less);
SelectSort(s._array, SeqListSize(&s));
PrintSeqList(&s);
}
int main()
{
TestSeqList3();
system("pause");
return 0;

}

测试结果:

1.TestSeqList();

2.TestSeqList2();

3.TestSeqList3();

在编写这份代码的过程中,我遇到了一些问题:比如在linux环境下编写的过程种出现了段错误:

 

出现段错误的原因是: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuruhua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值