线性表之顺序存储结构(顺序表)

Posted xiguazkb123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表之顺序存储结构(顺序表)相关的知识,希望对你有一定的参考价值。

目录

1.线性表

2.顺序存储结构(顺序表)

2.1顺序表一般可以分为:

 1. 静态顺序表:使用定长数组存储元素

  1.1静态顺序表:顺序表的大小是确定的,容量是固定的.

       结论:静态顺序表不是很常量,了解就行.

2. 动态顺序表:使用动态开辟的数组存储。(重要)

2.1优点:我们可以根据实际情况,对内存进行自由分配,从而不造成内存分配浪费!

2.2顺序表的定义

2.3顺序表的初始化

2.4顺序表增容:

2.5顺序表的删除

          思路  :

2.6顺序表的查找:   

        思路:

2.7顺序表的打印

2.8顺序表的释放

2.9顺序表的插入

2.10顺序表的头插头删

2.11顺序表的尾插尾删


1.线性表

线性表 linear list n 个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结 构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物 理上存储时,通常以数组和链式结构的形式存储。

2.顺序存储结构(顺序表)

顺序存储结构(顺序表)的定义:线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素

2.1顺序表一般可以分为:

 1. 静态顺序表:使用定长数组存储元素

  1.1静态顺序表:顺序表的大小是确定的,容量是固定的.

                        代码如下:
 
#define N 10000//运用宏定义,可以方便修改容量的大小
typedef int SLDataType;//运用宏定义,可以根据情况改变存储类型

// 静态顺序表
typedef struct SeqList
{
	SLDataType a[N];
	int size; // 表示数组中存储了多少个数据
}SL;

       结论:静态顺序表不是很常量,了解就行.

2. 动态顺序表:使用动态开辟的数组存储。(重要)

2.1优点:我们可以根据实际情况,对内存进行自由分配,从而不造成内存分配浪费!

2.2顺序表的定义

typedef int sldatatype;//根据实际情况,可以改变存储的类型

typedef struct {
	sldatatype* a;//开辟数组a
	int size;//多少个数据
	int capacity;//容量是多大

}sl;

 2.3顺序表的初始化

        //顺序表初始化
		void SeqListInit(SL* ps)
		{
			ps->a = NULL;
			ps->size = ps->capacity = 0;//赋值0
		}
        //指针设为空指针,ps指向的容量和数据都赋值0

 2.4顺序表增容:

                        请记住:两种情况都要扩容:

                                内存还未开辟

                                内存满了开辟

                       代码如下 

		void SeqListCheckCapacity(SL* ps)//顺序表扩容
		{
			// 如果没有空间或者空间不足,那么我们就扩容
			if (ps->size == ps->capacity)
			{
				int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity*sizeof(SLDataType));
				if (tmp == NULL)
				{
					printf("realloc fail\\n");
					exit(-1);//扩容都要这种判断是否成功
				}
		
				ps->a = tmp;
				ps->capacity = newcapacity;
			}
}

 

2.5顺序表的删除

		// 删除pos位置的数据
		void SeqListErase(SL* ps, int pos)
		{
			assert(pos >= 0 && pos < ps->size);//防止越界
		
			int begin = pos + 1;//遍历从0开始,要加1//取出要删掉的数字
			while (begin < ps->size)
			{
				ps->a[begin - 1] = ps->a[begin];//删掉的元素的位置后面每个元素都要往前挪.
				++begin;
			}
		
			ps->size--;
		}

          思路  :

                        1.取出要删掉的数字;

                        2.删掉的元素的位置后面每个元素都要往前挪.

2.6顺序表的查找:   

//输入你要查找的数据,找到这个数据就返回数据的下标,找不到就返回-1.
			int SeqListFind(SL* ps, SLDataType x)
			{
				for (int i = 0; i < ps->size; i++)
				{
					if (ps->a[i] == x)
					{
						return i;//查找对应那个数据的下标
					}
				}
			
				return -1;
            }

        思路:

               1.查找你要找的数据

               2.找得到,就返回该数据的下标

               3.找不到就返回-1

2.7顺序表的打印

       

		void SeqListPrint(SL* ps)
		{
			for (int i = 0; i < ps->size; ++i)
			{
				printf("%d ", ps->a[i]);
			}
			printf("\\n");
        }

2.8顺序表的释放

	顺序表释放://扩容就要释放//但只能有一个
		void SeqListDestory(SL* ps)
		{
			free(ps->a);
			ps->a = NULL;
			ps->capacity = ps->size = 0;//释放都要这样
		}

 2.9顺序表的插入

	//顺序表插入
		// 指定pos下标位置插入
		void SeqListInsert(SL* ps, int pos, SLDataType x)
		{
			// 温柔的处理方式
			/*if (pos > ps->size || pos < 0)
			{
				printf("pos invalid\\n");
				return;
			}*///防止越界
			// 粗暴的方式
			assert(pos >= 0 && pos <= ps->size);

            //两种方式都可以,但推荐粗暴的方式
		
			SeqListCheckCapacity(ps);
		
			// 挪动数据
			int end = ps->size - 1;
			while (end >= pos)
			{
				ps->a[end + 1] = ps->a[end];//增加位置,把前面的都推到后面去
				--end;
			}
		
			ps->a[pos] = x;
			ps->size++;

2.10顺序表的头插头删

	顺序表头插
	void SeqListPushFront(SL* ps, SLDataType x)
	{
		SeqListCheckCapacity(ps);//扩容

		//挪动数据
		int end = ps->size - 1;
		while (end >= 0)
		{
			ps->a[end + 1] = ps->a[end];
			--end;
		}
		ps->a[0] = x;
		ps->size++;
	
		//SeqListInsert(ps, 0, x);其实用插入就足够了
	}

	顺序表头删
	void SeqListPopFront(SL* ps)
	{
		assert(ps->size > 0);
	
	//挪动数据
			int begin = 0;
			while (begin < ps->size-1)
			{
				ps->a[begin] = ps->a[begin+1];
				++ begin;
			}
	
			int begin = 1;
			while (begin < ps->size)
			{
				ps->a[begin-1] = ps->a[begin];
				++begin;
			}
	
		ps->size--;

		//SeqListErase(ps, 0);用这个删除就足够了
	}
	

2.11顺序表的尾插尾删

	//顺序表尾插
	void SeqListPushBack(SL* ps, SLDataType x)
	{
		/*SeqListCheckCapacity(ps);
	
		ps->a[ps->size] = x;
		ps->size++;*/
		SeqListInsert(ps, ps->size, x);//用插入就可以代替
	}
	
	//顺序表尾删
	void SeqListPopBack(SL* ps)
	{
		// 温柔处理方式
		//if (ps->size > 0)
		//{
		//	//ps->a[ps->size - 1] = 0;
		//	ps->size--;
		//}
	
		// 暴力处理方式
		/*assert(ps->size > 0);
		ps->size--;*/
	
		SeqListErase(ps, ps->size-1);//用删除就可以删除
	}

 

以上是关于线性表之顺序存储结构(顺序表)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之线性表之顺序存储Java实现

线性链表之顺序表

数据结构线性表之顺序表ArrayList

数据结构学习总结线性表之顺序表

线性表之顺序存储结构与链式存储结构 及 应用

线性表之顺序存储结构实现(上)