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

这篇具有很好参考价值的文章主要介绍了数据结构——线性表之顺序表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一.线性表

二.顺序表实现

 2.1 概念及结构

 2.2 动态顺序表

2.2.1 初始化与销毁函数

2.2.2 打印函数

2.2.3 尾插函数

2.2.4 尾删函数

2.2.5 扩容函数

2.2.6 头插函数

2.2.7 头删函数

2.2.8 任意位置插入函数

2.2.9 查找函数

2.2.10 任意位置删除函数 

2.2.11 修改函数

三.完整代码

四.力扣经典例题

3.1 移除元素

3.2 合并有序数组

五.结语



一.线性表

数据结构——线性表之顺序表,数据结构,数据结构,算法

 二.顺序表实现

 2.1 概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:

  • 静态顺序表:使用定长数组存储(不好用)。
  • 动态顺序表:使用动态开辟的数组存储。

由于静态存储N定多了怕浪费,定少了又怕不够,我们简单提一嘴就好了,直接重点讲解动态顺序表。数据结构——线性表之顺序表,数据结构,数据结构,算法

 2.2 动态顺序表

数据结构——线性表之顺序表,数据结构,数据结构,算法

先创造一个头文件和两个源文件 。

 数据结构——线性表之顺序表,数据结构,数据结构,算法

这里为了方便修改,引入了2个typedef。

2.2.1 初始化与销毁函数

再接一个初始化函数:

注意:这里的实参传输到形参的过程是传值调用,这样形参只是一份实参的临时拷贝,需要实参随形参改变的话那就得用到传址调用。数据结构——线性表之顺序表,数据结构,数据结构,算法

//SeqList.h
#pragma once
#include <stdio.h>
#include <string.h>

typedef int SLDataType;
struct SeqList
{
	SQDataType*a;
	
	int size;     //存储有效数据个数
    int capacity; //空间大小
};
//如果想方便输入可以这么定义:
typedef struct SeqList SL;
//这样两个单词就可以用SL来替代了
void SLInit(SL* ps);
​void SLDestr(SL* ps); //动态内存开辟时候不销毁可能会导致内存泄漏
//Test.c
#include "SeqList.h"
int main()
{
	SL sl;
	SLInit(&sl);

	return 0;
}

返回SeqList.c文件中定义初始化与销毁函数。 

//SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void SLInit(SL* ps)
{
	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*4);//虽然一开始可以让空间大小和malloc都置空,但这样不方便测试,所以先给空间。
	if (ps->a == 0)
	{
		perror("malloc failed");//验证malloc所创空间是否为空
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;

}
void SLDestr(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

接下来我们开始定义各种接口并实现其功能

//SeqList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
struct SeqList
{
	SLDataType* a;
	int size;
	int capacity;
};
typedef struct SeqList SL;

void SLInit(SL* ps);
void SLDestr(SL* ps);
//打印函数
void SLprint(SL* ps);
//扩容函数
void SLCheckCapacity(SL* ps);
//头插尾插,头删尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);

//顺序表在pos位置位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDataType x);

//顺序表删除pos位置的值
void SeqListErase(SL* ps, size_t pos);
//查找函数
int SLFind(SL* ps, SLDataType x);
//修改函数
void SLModify(SL* ps, int pos, SLDataType x);

2.2.2 打印函数

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

2.2.3 尾插函数

关于realloc出来的空间不用free问题:

realloc分两种扩容(都有可能发生),当要扩容时会分析后面是否有足够空间来分配给你,不够就会扩容。

第一种是原地扩容:即在原数组中再开辟多余的空间,这时候开辟过后的空间地址其实与原数组a是一致的。

第二种是异地扩容:即不在原空间,而是重新开辟出新的空间,新空间满足了扩容需求的同时还会把原数组中的元素拷贝过来。这时候原来的空间就会销毁。

数据结构——线性表之顺序表,数据结构,数据结构,算法

其实我们可以测试一下relloc会是哪种扩容:

 这种地址相同的就是原地扩容了数据结构——线性表之顺序表,数据结构,数据结构,算法

当我们设置大一点时就变成异地扩容了

数据结构——线性表之顺序表,数据结构,数据结构,算法

因此解答了不用free的问题,因为realloc会自动帮你拷贝和释放。

//尾插函数
void SLPushBack(SL* ps, SLDataType x)
{
	if (ps->size == ps->capacity)
	{
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 *(sizeof(SLDataType)));
		if (tmp == NULL)
		{
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->size] = x;
	ps->size++;


}

接下来我们来测试一下尾插并验证是否扩容:

//Test.c
#include <stdio.h>
#include "SeqList.h"
int main()
{
	SL sl;
	SLInit(&sl);
	/*int* p1 = (int*)malloc(12);
	int* p2 = realloc(p1, 10);
	printf("%p, %p\n", p1, p2);*/
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	SLprint(&sl);
	SLDestr(&sl);

	return 0;
}

数据结构——线性表之顺序表,数据结构,数据结构,算法

2.2.4 尾删函数

数据结构——线性表之顺序表,数据结构,数据结构,算法

当我们让size--达到尾删时,是否需要把该处空间free掉?

答案是不行,因为malloc规定是整体创造空间并整体释放空间的,不能对整个空间中的一小处进行free,这是不被允许的。

数据结构——线性表之顺序表,数据结构,数据结构,算法

如果尾删函数仅仅是这样写肯定是会出错的,当我们尾删多次直至让size减到了负数,那么后面就不能再进行插入了,因为size已经越界回不来了。 所以我们得规定让它不能越界。

​
void SLPopBack(SL* ps)
{
	//只要size指向不大于0,就不给继续尾删并且提示报错
	assert(ps->size > 0);
	ps->size--;
}

​

2.2.5 扩容函数

为了避免每一次的接口函数都要写上扩容标准,我们直接定义一个扩容函数来方便我们调用。

//扩容函数
void SLCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
		if (tmp == NULL)
		{
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}

2.2.6 头插函数

基本思路是把空间里面原有的元素往后移动,记住是从最末尾的元素开始,如果从首元素开始移动,那么会覆盖掉后一个元素。

数据结构——线性表之顺序表,数据结构,数据结构,算法


//头插函数
void SLPushFront(SL* ps, SLDataType x)
{
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
}

我们继续来测试一下

//测试函数
void TestSeqList2()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	SLPopBack(&sl);
	
	SLprint(&sl);

	SLPushFront(&sl, 20);
	SLPushFront(&sl, 30);
	SLPushFront(&sl, 40);
	SLprint(&sl);
	SLDestr(&sl);

}

数据结构——线性表之顺序表,数据结构,数据结构,算法

2.2.7 头删函数

在头删函数中我们则是要做到把后一位的元素往前一位覆盖的效果,别忘了最后再ps->size--

数据结构——线性表之顺序表,数据结构,数据结构,算法

这段头删函数还是存在问题,如果size为0时,while不进入循环但size还是会--,这样又会造成之前的越界问题。所以要记得断言!

//头删函数
void SLPopFront(SL* ps)
{
	assert(ps->size > 0);
	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;

}

进行试验:先尾删3次,再头删一次

数据结构——线性表之顺序表,数据结构,数据结构,算法

数据结构——线性表之顺序表,数据结构,数据结构,算法

 2.2.8 任意位置插入函数

我们用断言来规定只能在数组元素范围内插入,接着再添加扩容函数。

既然要在某个位置中插入元素,那么它后面的元素就要往后移动,这里同样设置一个end,pos为我们想插入的下标。

数据结构——线性表之顺序表,数据结构,数据结构,算法

//顺序表在pos位置位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDataType x)
{
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;


	
}

接下来进行试验:我们先头插6 5 4 3 2 1,再从下标为1的位置中插入20.

数据结构——线性表之顺序表,数据结构,数据结构,算法

 数据结构——线性表之顺序表,数据结构,数据结构,算法

当我们完成Insert函数其实可以发现,它可以在头插和尾插函数里面进行复用。效果是一样的。

数据结构——线性表之顺序表,数据结构,数据结构,算法

数据结构——线性表之顺序表,数据结构,数据结构,算法

 2.2.9 查找函数

//查找函数
int SLFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}

	}
	return -1;
}

查找函数通常是跟其他接口函数搭配使用的,就比如与Insert搭配。

void TestSeqList3()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5); 
	SLprint(&sl);

	SeqListInsert(&sl, 3, 40);
	SLprint(&sl);
	int x;
	scanf("%d", &x);
	int pos = SLFind(&sl, x);
	if (pos != -1)
	{
		SeqListInsert(&sl, pos, x * 10);
	}
	SLprint(&sl);
	SLDestr(&sl);

}

数据结构——线性表之顺序表,数据结构,数据结构,算法

2.2.10 任意位置删除函数

老规矩,我们先断言pos只能在ps->size的范围内进行删除,当我们选定好要删除的下标时,需要把其后面的元素依次往前覆盖,这样就可以用覆盖来删除某一位置的元素了。

//顺序表删除pos位置的值
void SeqListErase(SL* ps, size_t pos)
{
	assert(pos >= 0 && pos < ps->size);//注意范围已经改变
	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;

}

进行试验:在任意位置插入函数实现的结果后我们再删除下标为1的元素

数据结构——线性表之顺序表,数据结构,数据结构,算法

数据结构——线性表之顺序表,数据结构,数据结构,算法

与Insert同理,Erase同样是可以复用的。

 2.2.11 修改函数

这里只需要注意断言使修改的位置在有效范围内就行了。

//修改函数

void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(pos >= 0 && pos < ps->size);
	ps->a[pos] = x;
}

 至此增删查改结束了,我们可以编辑一个菜单来总结这些功能:

数据结构——线性表之顺序表,数据结构,数据结构,算法

后面就慢慢用stitch语句慢慢完善就好了。 

 数据结构——线性表之顺序表,数据结构,数据结构,算法

三.完整代码

//SeqList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
struct SeqList
{
	SLDataType* a;
	int size;
	int capacity;
};
typedef struct SeqList SL;

void SLInit(SL* ps);
void SLDestr(SL* ps);
//打印函数
void SLprint(SL* ps);
//扩容函数
void SLCheckCapacity(SL* ps);
//头插尾插,头删尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);

//顺序表在pos位置位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDataType x);

//顺序表删除pos位置的值
void SeqListErase(SL* ps, size_t pos);
//查找函数
int SLFind(SL* ps, SLDataType x);
//修改函数
void SLModify(SL* ps, int pos, SLDataType x);
//SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void SLInit(SL* ps)
{
	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//虽然一开始可以让空间大小和malloc都置空,但这样不方便测试,所以先给空间。
	if (ps->a == 0)
	{
		perror("malloc failed");//验证malloc所创空间是否为空
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;

}
void SLDestr(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

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

//扩容函数
void SLCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
		if (tmp == NULL)
		{
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}

//尾插函数
void SLPushBack(SL* ps, SLDataType x)
{
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;


}

//尾删函数
void SLPopBack(SL* ps)
{
	//只要size指向不大于0,就不给继续尾删并且提示报错
	assert(ps->size > 0);
	ps->size--;
}

//头插函数
void SLPushFront(SL* ps, SLDataType x)
{
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
}


//头删函数
void SLPopFront(SL* ps)
{
	assert(ps->size > 0);
	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;

}

//顺序表在pos位置位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDataType x)
{
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;


	
}
//查找函数
int SLFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}

	}
	return -1;
}

//顺序表删除pos位置的值
void SeqListErase(SL* ps, size_t pos)
{
	assert(pos >= 0 && pos < ps->size);//注意范围已经改变
	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;

}
//修改函数

void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(pos >= 0 && pos < ps->size);
	ps->a[pos] = x;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//Test.c
#include <stdio.h>
#include "SeqList.h"
void TestSeqList1()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	SLPopBack(&sl);
	SLprint(&sl);
	SLDestr(&sl);

}
void TestSeqList2()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	SLPopBack(&sl);
	
	SLprint(&sl);

	SLPushFront(&sl, 20);
	SLPushFront(&sl, 30);
	SLPushFront(&sl, 40);
	SLprint(&sl);
	SLDestr(&sl);

}

void TestSeqList3()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5); 
	SLprint(&sl);

	SeqListInsert(&sl, 3, 40);
	SLprint(&sl);
	int x;
	scanf("%d", &x);
	int pos = SLFind(&sl, x);
	if (pos != -1)
	{
		SeqListInsert(&sl, pos, x * 10);
	}
	SLprint(&sl);
	SLDestr(&sl);

}


int main()
{
	/*SL sl;*/
	/*SLInit(&sl);*/
	/*int* p1 = (int*)malloc(12);
	int* p2 = realloc(p1, 10);
	printf("%p, %p\n", p1, p2);*/
	//TestSeqList1();
	//TestSeqList2();
	TestSeqList3();

	return 0;
}

四.力扣经典例题

3.1 移除元素

链接:力扣——移除元素

数据结构——线性表之顺序表,数据结构,数据结构,算法

 数据结构——线性表之顺序表,数据结构,数据结构,算法

数据结构——线性表之顺序表,数据结构,数据结构,算法

 一般我们的思路就是2.2.10任意位置删除元素的思想:

挨个遍历,如果指向的下标元素与val相同,那么把后面的元素依次覆盖,依次反复做到删除

数据结构——线性表之顺序表,数据结构,数据结构,算法

 假设第一次排列移动了n次,那么第2次删除排列就是n-1次,等差数列求和一共执行了n^2次数据结构——线性表之顺序表,数据结构,数据结构,算法

 数据结构——线性表之顺序表,数据结构,数据结构,算法

 新数组拷贝回去后因为是malloc出来的,所以再把它释放掉就行了。空间复杂度为O(N)

这个想法核心是两个指针:一开始先让它们指向同一位置,用src来识别该值是否是val,如果不是就把这个值传到dst那里去,在同等指向时好像没什么不同,因为dst确实与src指向同一方向,然后二者共同向下一位进发。

转折点就是当src指向了第一个2(val的值)时,dst虽然也指向了2,但是dst不动,src向下一位进发,又指向了第二个2,dst还是不动,src继续进发指向了3.

最精彩的地方,因为src指向的3不是val(2),所以src会把3传给dst,那么dst原本指向的第一个2就会被改变成3,以此类推我们会发现当src走完时,dst已经把2都给覆盖了。

数据结构——线性表之顺序表,数据结构,数据结构,算法

 数据结构——线性表之顺序表,数据结构,数据结构,算法

另外我们也不用担心在str出去后原数组还有val要怎么办,因为问题是要求返回新数组的长度,所以dst的指向本身就可以代表新数组长度,所以不用管dst后面的元素。

int removeElement(int* nums, int numsSize, int val)
{
	int n = numsSize;
	int src = 0;
	int dst = 0;
	while (src < n)
	{
		if (nums[src] != val)
		{
			nums[dst] = nums[src];
			src++;
			dst++;
			
		}
		else if (nums[src] == val)
		{
			src++;
		}
	}
	return dst;
}

3.2 合并有序数组

链接:力扣——合并有序数组

数据结构——线性表之顺序表,数据结构,数据结构,算法

 数据结构——线性表之顺序表,数据结构,数据结构,算法

数据结构——线性表之顺序表,数据结构,数据结构,算法

这一道题也可以通过使用双指针的方法来进行合并有序数组:

首先,我们让两个指针都分别指向数组末尾的有效元素,然后同时进行比较。一开始a指向3,b指向6,6比3大,那么把b指向的6放入c中,同时b指向前一位的5,c也指向前一位的0.

a因为3比6小,所以还是指向a。

接着我们开始第二轮比较,指向3的a与指向5的b中,b更大所以重复操作b--,c在接受b传送的5后也跟着向前一位,c--。

现在a仍指向3,而b已经指向2了,3比2大,所以换成a把3传给c,然后二者都向前一位--。

至此,a向前一位指向2,b也指向2,而c指向的数值是3,让其中一位传给c即可,把3变成2,剩下的就不用处理了。

数据结构——线性表之顺序表,数据结构,数据结构,算法

不过有一个问题:

当有负数的情况出现时,我们重复上述操作会发现nums1a的指向已经移出下标了没办法再排序了,而-2和-5却还没有排进去。

数据结构——线性表之顺序表,数据结构,数据结构,算法

所以就需要当nums1数组已经结束时再添加一个条件,让没结束的nums2继续拷贝。

数据结构——线性表之顺序表,数据结构,数据结构,算法

void merge(int* nums1, int sums1Size, int m, int* nums2, int sum2Size, int n)
{
	int end1 = m - 1;//第一个数组有效元素尾部
	int end2 = n - 1;//第二个数组有效元素尾部
	int end = m + n - 1;//第一个数组尾部
	while (end1 >= 0 && end2 >= 0)
	{
		if (nums1[end1] > nums2[end2])
		{
			nums1[end] = nums1[end1];
			end1--;
			end--;
		}
		else
		{
			nums1[end] = nums2[end2];
			end2--;
			end--;
		}
	}
	while (end2 >= 0)
	{
		nums1[end] = nums2[end2];
		end2--;
		end--;
	}
}

五.结语

我们可以发现做上述两道题和分析顺序表的时候最重要的思想就是学会画图,只要画图逻辑够清晰,那么代码是很容易写出来滴~文章来源地址https://www.toymoban.com/news/detail-722610.html

到了这里,关于数据结构——线性表之顺序表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【数据结构】线性表之栈、队列

    【数据结构】线性表之栈、队列

    前面两篇文章讲述了关于线性表中的顺序表与链表,这篇文章继续讲述线性表中的 栈和队列。 这里讲述的两种线性表与前面的线性表不同,只允许在一端入数据,一段出数据,详细内容请看下面的文章。 顺序表与链表两篇文章的链接: 线性表之顺序表 线性表之链表 注意:

    2024年02月06日
    浏览(38)
  • 【数据结构】线性表之链表

    【数据结构】线性表之链表

    上一篇文章讲述了线性表中的顺序表,这篇文章讲述关于链表的定义、类别、实现、多种不同链表的优缺点和链表与顺序表的优缺点。 关于上一篇文章的链接:线性表之顺序表 链表是一种物理存储结构上 非连续、非顺序 的存储结构,数据元素的逻辑顺序是通过链表中的指针

    2024年02月05日
    浏览(42)
  • 数据结构:线性表之-单向链表(无头)

    数据结构:线性表之-单向链表(无头)

    目录 什么是单向链表 顺序表和链表的区别和联系 顺序表: 链表: 链表表示(单项)和实现 1.1 链表的概念及结构 1.2单链表(无头)的实现 所用文件 将有以下功能: 链表定义 创建新链表元素 尾插 头插 尾删 头删 查找-给一个节点的指针 改 pos位置之前插入 删除pos位置的值 成品

    2024年02月09日
    浏览(39)
  • 数据结构与算法-头歌【1】顺序线性表--课上练

      本意是整理和复习,理解不深或者有错误的评论区提出即可。 只有第一关的代码里面有结构体的定义,其余我只放了功能函数。 任务描述 本关要求按照完成顺序表数据类型定义,并初始化一个顺序线性表。 编程要求 顺序线性表数据结构定义如下: 本关的编程任务是补全

    2023年04月25日
    浏览(15)
  • 【数据结构与算法】二、线性表的顺序表示【硬核】

    【数据结构与算法】二、线性表的顺序表示【硬核】

    图书表的顺序存储结构类型定义: 在调用函数的过程中,当形参为引用类型时,实参和形参占用了相同的空间 2.4.1 线性表的基本操作: 2.4.2 线性表L的初始化 2.4.3 销毁和清空线性表L 2.4.4 求线性表L的长度以及判断线性表L是否为空 2.4.5 顺序表的取值(根据位置i获取相应位置

    2023年04月26日
    浏览(14)
  • 数据结构:线性表之-循环双向链表(万字详解)

    数据结构:线性表之-循环双向链表(万字详解)

    目录 基本概念 1,什么是双向链表 2,与单向链表的区别 双向链表详解 功能展示: 1. 定义链表 2,创建双向链表 3,初始化链表 4,尾插 5,头插 6,尾删 判断链表是否被删空 尾删代码 7,头删 8,pos位置之前插入 优化后的头插 优化后的尾插 9,删除pos位置的节点 优化后的尾删 优

    2024年02月09日
    浏览(11)
  • C语言数据结构——线性表之栈和队列

    C语言数据结构——线性表之栈和队列

    为什么会定义栈和队列这两种数据结构呢? 原因在于: 之所以会定义栈和队列这样的数据结构 是因为他们有两大特性 : 第一: 他们可以保存程序运行路径中各个点的信息,以便用于回溯操作或其他需要访问已经访问过的节点信息的操作。 比如: 栈用于解决迷宫问题,就

    2023年04月11日
    浏览(39)
  • 数据结构第三课 -----线性表之双向链表

    数据结构第三课 -----线性表之双向链表

    🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 ​🎂 作者介绍: 🎂🎂 🎂 🎉🎉🎉🎉🎉🎉🎉 🎂 🎂作者id:老秦包你会, 🎂 简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂 喜欢学习C语言和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂

    2024年02月05日
    浏览(41)
  • 【数据结构】线性表之单链表(讲解实现——带动图理解)

    【数据结构】线性表之单链表(讲解实现——带动图理解)

    单链表的优点 1.头部和中间插入或删除数据效率高,无需挪动。 2.按照需求申请释放空间,无需担心空间不够用。 单链表的缺点 1.不可以进行下标随机访问。 2.复杂度是O(n) 3.反向遍历困难 单链表是线性表的一种,单链表是链式存储的线性表,不同于单链表, 链表在内存空间

    2024年02月06日
    浏览(47)
  • 数据结构三:线性表之单链表(带头结点单向)的设计与实现

    数据结构三:线性表之单链表(带头结点单向)的设计与实现

            线性表的链式存储结构正是所谓的单链表,何谓单链表?通过地址将每一个数据元素串起来,进行使用,这可以弥补顺序表在进行任意位置的插入和删除需要进行大量的数据元素移动的缺点,只需要修改指针的指向即可;单链表的种类又可划分为很多种,本篇博客详

    2024年02月19日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包