数组、链表、队列和栈,C语言实现

这一章主要学习数组和链表,并分别用数组和链表实现队列及栈的功能。
在学习C语言的时候,我们已经学习过了数组,那时对数组的操作主要是生成数组、对数组的元素赋值、读取数组中的元素等内容,并没有对数组中的元素进行删除、插入操作。在本章内容中,我们将对数组的其它方面进行讲解。链表是一个全新的概念,里面要用到指针。这是C语言的一个特色,也是比较难的一部分内容。
数组和链表是所有数据结构中最基础的两种,同时,它们也是队列、栈、以及以后要学习到的 (二叉) 树、堆、图、串 (我们不讨论串) 等数据结构的基础,几乎所有的算法都是在数组和链表上实现的。可以这么说,如果没有数组和链表,整个数据结构和算法就没法实现了。

1 数组
好了,我们就从最简单的一维数组开始吧。
C语言中,申明数组有两种方式:
① 自动申请,例如int arr [10]; 表示让C语言自动申请一段长度够10个int类型数据存放的空间,也就是10 * 4 = 40个字节。这种方式的好处是不需要让开发者申请内存空间,而且用完之后编译器自动回收内存,不需要开发者手动回收。缺点是数组大小一定要在申请的时候指定,且一定要用常量指定,不能用变量指定。这个缺点是很明显的,我们常常申请一个足够大的空间,从而保证数组的空间够用。这样经常会出现浪费的情况。

② 手动向操作系统申请内存空间。这种方式与自动申请就刚好相反。好处是可以用一个变量临时确定需要申请多大的内存空间,这样就可以不浪费。缺点是需要开发者手动申请,用完之后又需要手动回收内存。对C语言比较熟悉的朋友一定知道,C语言最容易出问题的就是指针,其实也就是内存问题。所以用这种方式时一定要比较当心才行。关于手动向操作系统申请内存空间并建立数组的方式我们在用到的时候再讨论。

注:只有C语言存在两种方式申请数组的情况,其它语言 (C++、Java、C#、Python等) 都可以用变量在申请数组时确定数组大小,且都可以让语言本身回收垃圾。

好,我们让编译器帮我们申请一个数组:int arr [10];

你看,这个数组中每一个元素都是int类型的,占用的内存空间都是4个字节。这样的话,我们如果要找第n个元素,只需要知道arr的首地址,然后计算首地址 + n * 4,它就是存放第n个元素的地址了。这样是不是很容易?C语言的编译器甚至帮我们做的更好:我们只需要输入arr[n]就可以获得第n个元素了,如果用指针的方式,那就是*(arr + n)。也就是说,随机读取、设置数组中一个元素的时间复杂度为O(1)。代码如下:

int arr[10] = {
   1, 2, 3, 4, 5};
printf("%d <--> %d\r\n", arr[3], *(arr + 3));

下面我们看一下在数组中插入一个数据的情况:如果要在第二个位置插入数据9,我们需要分三步走:
第一步,计算数组中有几个元素:5
第二步,从最后一个元素开始,每一个元素都往后移动一个位置。一共移动4个元素。这样就把第二个的位置空出来了。
第三步,在第二个的位置放置元素9。

用这种方式,对于一个有n个元素的数组,如果要在最前面插入一个数据,需要移动n个元素,然后再插入一个数据。总的时间复杂度为O(N / 2) = O(N)。

void insertNumAt(int index, int num) 
{
   
	for(int i = size; i >= index; i--)
	{
   
		arr[i] = arr[i - 1]; //每个元素都往后移动一个位置 
	}
	arr[index] = 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值