23-链表

可变数组

接口

  • Array array _create(int init_size); 创建数组
  • void array_free(Array *a); 释放空间
  • int array_size(const Array *a); 数组有多少单元可以用
  • int *array _at(Array *a , int index); 访问数组中的某个单元
  • void array_inflate(Array *a , int more_size); 让数组长大

the Array

typedef struct{
	int *array;
	int size;
}Array;

array _creat()

Array array _create(int init_size)
{
	Array a;
	a.size = init_size;
	a.array = (int*)malloc(sizeof(int)*init_size);
	
	return a;
}

array _free()

void array_free(Array *a)
{
	free(a->array);
	a->array = NULL;
	a->size = 0;
}

array _size()

 int array_size(const Array *a)
 {
	 return a->size;
 }

array _at() (封装作用)

int *array _at(Array *a , int index)
{
	if(index>=a->size){   //有扩展功能
		array_inflat(a,(index/BLOCK_SIZE+1)*BLOCK_SIZE-a->size);  //此处BLOCK_SIZE是每次增加的常量
	}
	
	return &(a->array[index]);
}

此处有第二种访问方法:
用array_get() , array_set()
请添加图片描述

array _inflate()

void array_inflate(Array *a , int more_size)
{
	int *p = (int*)malloc(sizeof(int)*(a->size+more_size));
	int i;
	for(i=0,i<a->size,i++){
		p[i] = a->array[i];
	}
	free(a->array);     //把原来的地址内空间释放
	a->array = p;    //赋新的地址
	a->size += more_size;
}

main()

int main(int argc,char const *argv[])
{
	Array a = array_creat(100);     //创建数组
	printf("%d\n",array_size(&a));   //数组大小
	*array_at(&a,0) = 10;  //通过函数找到位置并解引用赋值
	printf("%d",*array_at(&a,0))int number = 0;
	int cnt = 0;
	while(number = -1){
		scanf("%d",&number);
		if(number!=-1){
			*array_at(&a,cnt++) = number;  //cnt++变化需要的空间大小,at函数有扩展作用
		}
	}
	array_free(&a);  //释放内存
	
	return 0;
}

可变数组的缺陷

会遇到内存不够用,或无法在申请内存的情况,而且每次申请都需要拷贝,效率低,故需要用到链表。

链表

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

typedef struct _node{   //定义结构
	int value;  //数据
	struct _node *next;  连接下一个结构
}Node;

typedef struct _list{
	Node *head;
}List;

void add(List *phead,int number);
void print(List *plist);
int main(int argc,char const *argv[])
{
	List list;
	list.head  = NULL;  //头指针放空
	int number;
	do{                    //每次循环都需要从头开始 
		scanf("%d",&number);
		if(number!=-1){
			add(&list,number);  
		}
		
	}while(number!=-1);
	//搜索
	printf("接下来是搜索:\n");
	 print(&list);
	 //链表的删除
	 scanf("%d\n",number);
	 Node *q;
	 Node *p;
	 int isFound = 0;
	for(q = NULL,p = list.head ; p ; q=p,p = p->next ){
	 	if(p->value == number){
	 		q->next = p->next ;
		 }else{
		 	list.head = p->next ;  //找的数在开头的情况
		 }
		 free(p);
		 break ;
	 } 
	//链表的清除
	for(p = list.head ;p ;p = q){
		q = p->next ;
		free(p);
	} 
	 
	return 0;
}

void add(List *plist,int number)     //链表函数 
{
	Node *p = (Node*)malloc(sizeof(Node));  //指针p申请空间
	p->value = number;  //填入数字
	p->next = NULL;  //填入空
	Node *last = plist->head;
	if(last){          //找到空
		while(last->next){    //last指向next的值是否为NULL来判断是否连接下一个结构
			last = last->next;  //由于原来位置有值last指向下一个结构
		}
		last->next = p;  //由于last指向的next为空,在空结构写入*p值的结构(此时value中有数据,next中为NULL)
	}else{
		plist->head = p;
	}
}

void print(List *plist){            //链表搜索 
	Node *p;
	for(p = plist->head ; p ; p = p->next ){
		printf("%d\t",p->value );
	}
	printf("\n");
}

链表函数

void add(List *plist,int number)     //链表函数 
{
	Node *p = (Node*)malloc(sizeof(Node));  //指针p申请空间
	p->value = number;  //填入数字
	p->next = NULL;  //填入空
	Node *last = plist->head;
	if(last){          //找到空
		while(last->next){    //last指向next的值是否为NULL来判断是否连接下一个结构
			last = last->next;  //由于原来位置有值last指向下一个结构
		}
		last->next = p;  //由于last指向的next为空,在空结构写入*p值的结构(此时value中有数据,next中为NULL)
	}else{
		plist->head = p;
	}
}

画图理解:

请添加图片描述

链表搜索

void print(List *plist){            //链表搜索 
	Node *p;
	for(p = plist->head ; p ; p = p->next ){
		printf("%d\t",p->value );
	}
	printf("\n");
}

链表删除

通过两个指针,直接从前一个结构连接到后一个结构跳过中间的数,来删除中间的数

 scanf("%d\n",number);
	 Node *q;
	 Node *p;
	 int isFound = 0;
	for(q = NULL,p = list.head ; p ; q=p,p = p->next ){
	 	if(p->value == number){
	 		q->next = p->next ;
		 }else{
		 	list.head = p->next ;  //找的数在开头的情况
		 }
		 free(p);
		 break ;
	 } 

链表清除

for(p = list.head ;p ;p = q){
		q = p->next ;
		free(p);
	} 

此节有链表构成的一些过程看翁恺老师原视频:MOOC

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值