数据结构---顺序表的有关实现

顺序表:用一段地址连续的存储单元依次存储数据元素的线性结构

地址连续的空间,一般情况下采用数组,但数组有静态数组和动态数组,所以顺序表分为静态顺序表和动态顺序表。

静态顺序表的有关实现

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define MAX_SIZE 100
typedef int DataType;

typedef struct SeqList{
	DataType array[MAX_SIZE];
	int size;   //1.保存数据表里已经有了的数据个数
	            //2.当前可用下标
}SeqList;

//初始化(函数设计)
void SeqListInit(SeqList *pSeq)
{
	//1.初始化size
	//2.可能需要把容器空间清空下(但是最后确定不需要)
	assert(pSeq	!= NULL);
	pSeq->size = 0;
} 

//销毁
void SeqListDestroy(SeqList *pSeq)
{
	assert(pSeq	!= NULL);
	pSeq->size = 0;
}

//增
//1.尾插
void SeqListPushBack(SeqList *pSeq, DataType data)
{
	assert(pSeq);
	//特殊情况(满了)
	if(pSeq->size >= MAX_SIZE){
		assert(0);
		printf("满了\n");
		return ;
	}
	//通常情况
	pSeq->array[pSeq->size] = data;
	pSeq->size++;
}

//2.头插
void SeqListPushFront(SeqList *pSeq, DataType data)
{
	int i = 0;
	assert(pSeq);
	//特殊情况(满了)
	if(pSeq->size >= MAX_SIZE){
		assert(0);
		printf("满了\n");
		return ;
	}
	//通用情况
	for(i=pSeq->size; i>0; i--)
	{
		pSeq->array[i] = pSeq->array[i-1];
	}
	pSeq->array[0] = data;
	pSeq->size++;
}

//3.插入
void SeqListInsert(SeqList *pSeq, int pos, DataType data)
{
	int i = 0;
	assert(pSeq);
	//特殊情况(满了)
	if(pSeq->size >= MAX_SIZE){
		assert(0);
		printf("满了\n");
		return ;
	}
	//通常情况
	for(i=pSeq->size; i>pos; i--)
	{
		pSeq->array[i] = pSeq->array[i-1];
	}
	pSeq->array[pos] = data;
	pSeq->size++;
}

//删
//1.尾删
void SeqListPushPop(SeqList *pSeq)
{
	assert(pSeq);
	//特殊情况(空了)
	if(pSeq->size <= 0){
		printf("空了\n");
		assert(0);
		return ;
	}
	//通常情况
	pSeq->size --;
}

//2.头删
void SeqListPopFront(SeqList *pSeq)
{
	int i = 0;
	assert(pSeq);
	//特殊情况(空了)
	if(pSeq->size <= 0){
		printf("空了\n");
		assert(0);
		return ;
	}
	//通常情况
	for(i=0; i<pSeq->size-1; i++)
	{
		pSeq->array[i] = pSeq->array[i+1];
	}
	pSeq->size--;
}

//3.删除
void SeqListErase(SeqList *pSeq, int pos)
{
	int i = 0;
	assert(pSeq);
	assert(pos>=0 && pos<pSeq->size);
	//特殊情况(空了)
	if(pSeq->size <= 0){
		printf("空了\n");
		assert(0);
		return ;
	}
	//通常情况
	for(i=pos; i<pSeq->size-1; i++)
	{
		pSeq->array[i] = pSeq->array[i+1];
	}
	pSeq->size--;
}

//查询
//找到第一个遇到的数的下标,没找到返回-1(更理想的返回类型ssize_t)
int SeqListFind(SeqList *pSeq, DataType data)
{
	int i = 0;
	for(i=0; i<pSeq->size; i++)
	{
		if(data == pSeq->array[i]){
			return i;
		}
	}
	return -1;
}

//删除的第二种形态(根据数据删除)
//1.遇到的第一个数据
void SeqListRemove(SeqList *pSeq, DataType data)
{
	int pos = SeqListFind(pSeq,data);
	if(pos == -1)
	{
		return ;
		SeqListErase(pSeq,pos);
	}
}

//2.遇到的所有数据
void SeqListRemoveAll(SeqList *pSeq,DataType data)
{
	int i,j;
	for(i=0,j=0; i<pSeq->size; i++)
	{
		if(data != pSeq->array[i]){
			pSeq->array[j] = pSeq->array[i];
			j++;
		}
	}
	pSeq->size = j;
}

//打印
void SeqListPrint(const SeqList *pSeq)
{
	int i = 0;
	assert(pSeq != NULL);

	for(i = 0; i < pSeq->size; i++)
	{
		printf("%d ",pSeq->array[i]);
	}
	printf("\n");
}

void Test()
{
	SeqList seqlist;
	SeqListInit(&seqlist);//1.指针空间小2.改变值

	SeqListPushBack(&seqlist,1);
	SeqListPushBack(&seqlist,2);
	SeqListPushBack(&seqlist,3);
	SeqListPushBack(&seqlist,4);
	SeqListPrint(&seqlist);

	SeqListPushPop(&seqlist);
	SeqListPrint(&seqlist);

	SeqListPushFront(&seqlist,10);
	SeqListPrint(&seqlist);

	SeqListPopFront(&seqlist);
	SeqListPrint(&seqlist);

	SeqListInsert(&seqlist, 1, 100);
	SeqListPrint(&seqlist);

	SeqListErase(&seqlist, 2);
	SeqListPrint(&seqlist);
}

static void Swap(DataType *a, DataType *b)
{
	DataType t = *a;
	*a = *b;
	*b = t;
}

//冒泡排序
void SeqListBubble(SeqList *pSeq)
{
	int isSort;//标记是否交换
	int i, j;
	for(i=1; i<pSeq->size; i++)
	{
		isSort = 1;
		for(j=0; j<pSeq->size-1-i; j++)
		{
			if(pSeq->array[j] > pSeq->array[j+1]){
				Swap(pSeq->array+j, pSeq->array+(j+1));
				isSort = 0;
			}
			if(isSort == 0)
				break;
		}
	}
}

//选择排序
void SeqListSort(SeqList *pSeq)
{
	int min = 0;
	int max = pSeq->size-1;
	int minPos,maxPos;
	while(min<max)
	{
		int i = 0;
		minPos = min;
		maxPos = min;
		for(i=min+1; i<=max; i++)
		{
			if(pSeq->array[i]<pSeq->array[minPos])
			{
				minPos = i;
			}
			if(pSeq->array[i]>pSeq->array[maxPos])
			{
				maxPos = i;
			}
		}
		Swap(pSeq->array+min,pSeq->array+minPos);
		if(min == maxPos){
			maxPos = minPos;
		}
		Swap(pSeq->array+max,pSeq->array+maxPos);

		min++;
		max--;
		}
	}


void Test2()
{
	SeqList seqlist;
	SeqListInit(&seqlist);//1.指针空间小2.改变值

	SeqListPushBack(&seqlist,4);
	SeqListPushBack(&seqlist,5);
	SeqListPushBack(&seqlist,3);
	SeqListPushBack(&seqlist,8);
	SeqListPushBack(&seqlist,6);
	SeqListPushBack(&seqlist,9);
	SeqListPushBack(&seqlist,2);
	SeqListPushBack(&seqlist,10);
	SeqListPrint(&seqlist);

	SeqListSort(&seqlist);
	SeqListPrint(&seqlist);

	SeqListBubble(&seqlist);
	SeqListPrint(&seqlist);
}

动态顺序表的有关实现:

#pragma once

#include <stdlib.h>
#include <assert.h>

typedef int DataType;

#define INIT_CAPACITY (3)

typedef struct SeqListD {
	DataType *	parray;
	int capacity;	// 当前容量 等于 静态顺序表 MAX_SIZE
	int size;		// 同静态顺序表
}	SeqListD;

// 初始化/销毁/所有插入(尾插)
// 其他和静态顺序表完全一样

void SeqListDInit(SeqListD *pSeq)
{
	// 为了获得容器空间
	pSeq->capacity = INIT_CAPACITY;
	pSeq->parray = (DataType *)malloc(sizeof(DataType)* pSeq->capacity);
	assert(pSeq->parray);

	// 这个和静态顺序表一样
	pSeq->size = 0;
}

void SeqListDDestroy(SeqListD *pSeq)
{
	free(pSeq->parray);

	pSeq->capacity = 0;
	pSeq->parray = NULL;
	pSeq->size = 0;
}

static void ExpandIfRequired(SeqListD *pSeq)
{
	DataType *newArray = (DataType *)malloc(sizeof(DataType)* pSeq->capacity);
	int i = 0;
	// 扩容条件
	if (pSeq->size < pSeq->capacity) {
		// 没满
		return;
	}

	// 扩容
	pSeq->capacity *= 2;

	// 1. 申请新空间
	
	assert(newArray);
	// 2. 数据搬移
	for (i = 0; i < pSeq->size; i++) {
		newArray[i] = pSeq->parray[i];
	}
	// 3. 释放老空间,关联新空间
	free(pSeq->parray);
	pSeq->parray = newArray;
}

void SeqListDPushBack(SeqListD *pSeq, DataType data)
{
	// 静态:如果满了,不处理/报错
	// 动态:加入扩容机制
	ExpandIfRequired(pSeq);

	pSeq->parray[pSeq->size] = data;
	pSeq->size++;
}

// 同理,所有插入都需要加入扩容机制

void Test3()
{
	SeqListD sld;
	SeqListDInit(&sld);

	SeqListDPushBack(&sld, 1);
	SeqListDPushBack(&sld, 2);
	SeqListDPushBack(&sld, 3);
	//  这下面会扩容
	SeqListDPushBack(&sld, 4);
	SeqListDPushBack(&sld, 5);
}

动态顺序表的实现大部分和静态顺序表都很相似,只不过动态顺序表要加上扩容机制。

主函数:

#include "seqlist.h" 
#include "seqListd.h"

int main()
{
	//Test();
	//Test2();
	Test3();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值