【数据结构】顺序表和单链表(C语言版)


前言

提示:本篇记录自学《大话数据结构》的链表章节
主要是代码的理解,不会出现很多的概念定义
学习数据结构最好的办法就是画图相当于是一步步调试


一、顺序存储之顺序表



定义

顺序表也叫(顺序存储结构) ,是一种用一段地址连续的存储单元依次存储线性表的数据元素。



顺序表的示意图

在这里插入图片描述

二、线性表的顺序存储结构

#define Max_sz  20      /代表数组最大容量
typedef int ElemType;   /代表元素类型
typedef sturct
{
	ElemType data[Max_sz];
	int length:    			/记录数组中元素的有效个数
}SqList;                	/重定义这个结构体的名字叫SqList也就是顺序表的意思

SqList 的数组存放元素 length记录有效元素个数





三.顺序表的增删查改


通过下标 查询函数

前提:顺序表以创立

代码如下:

#typedef int Status;   /Status  是返回值的类型的意思
#define OK 1           /代表成功查找
#define ERROR 0		   /代表查找失败

Status GetElem(SqList L, int i, ElemType* e)
{
	if(L.length ==0 || i<1 || i>L.length)   //报错的条件
		return ERROR;
	*e=L.data[i-1];   //返回目标元素给e
	return OK;
}



详解

if(L.length ==0 || i<1 || i>L.length)
三个条件:length不能为0为0就代表是空表 || 查找的下标不能小于1 || 查找下标不能大于有效长度
因为数组下标是从0开始,而位置理所当然是1开始 所以*e =data[i-1]



通过下标 插入函数

前提:顺序表以创立

代码如下:

// Status  是返回值的类型的意思   #typedef int Status;

Status Eleminsert(SqList* L, int i, ElemType e)
{
	int k;
 	if( L->length == Max_sz || i<1 || i > L->length+1)
 		return ERROR;
 		
 	if(i<=L->length)                 //元素遍历后移
 	{
 		for(k=L->length-1;k>=i;k++)
			L->data[k+1]=L->data[k];
		
 	}
 	L->data[i-1]=e;
 	L->length++;          			//插入完长度要加1
 	return OK;

}


详解

if( L->length == Max_sz || i<1 || i > L->length+1)
三个条件:当length ==max_sz 说明列表满了 || 不解释 || 这里length+1 是因为可以插在最后
if(i<=L->length) 当你插入的位置不是在表尾 就需要进行数组的后移
for(k=L->length-1;k>=i;k--)
后移我们肯定是要从最后一个开始移动 要不然会把前面的数据覆盖

k=L->length-1 下标的最后一个元素(因为数组是从0下标开始)
k>=i 因为原i下标的元素也许后移




通过下标 删除函数

前提:顺序表以创立

代码如下:

Status Elemdel(SqList* L,int i, ElemType* e)
{
	int k;
	if (L->length == 0 ||  i < 1 || i > L->length )
		return ERROR;
	
	*e = L->data[i - 1];

	if (i < L->length)                      	 //当删除元素不在表尾   数组往前移    
	{
		for (k = i; k < L->length ; k++)
		{
			L->data[k-1] = L->data[k];
		}
	}
	L->length--;
	return OK;
}


详解

for (k = i; k < L->length ; k++) 这里让 k=i 是因为要把i下标也覆盖。



通过下标 修改函数

前提:顺序表以创立

代码如下:

Status GetElem(SqList * L, int i, ElemType e)
{
     if(L->length == 0 || i<1  || i> L->length)
     	return ERROR;
     
     L->data[i-1]=e;
     return OK;
}

四、链式存储之单链表



定义

链表中两个逻辑位置在一起的元素,物理地址并不连续,因为链表的每个会有一个指向下一项的指针,指针所指地址对应的值才是与该元素逻辑上相邻的值。本文我们会从单链表出发,循序渐进带大家了解双链表和循环链表。



单链表的示意图

在这里插入图片描述

五、单链表的链式存储结构

代码如下(示例):



注意:本篇博客都为有头结点的单链表;

typedef struct Node
{
   ElemType data;     //数据域
   struct Node*next;  //指针域
}Node;
typedef Node* Linklist;    



六、顺序表的增删查创



通过下标 查找元素

前提:顺序表以创立

代码如下:

#define OK  1
#define ERROR -1
typedef int Status;

Status GetElem(Linklist L,int i ,ElemType e)
{
	int j;
	Linklist p;  //创立指针p
	p=L->next;   //指针p指向头节点的下一个元素==首元素
	j=1;		 //计数器
	
	while(p && j<i)   //当p指针不为空 并且 让j小于i
	{
		p=p->next;   // 让p遍历指向下一个结点
		++j;         //这轮循环的目的是要让指针p指向要查找的下标的前一个		元素
	}
	if(P || j>i)   //当指针为NULL 或者j大于i
		return ERROR;
	*e=p->data;
	return Ok;
	

}



通过下标 插入元素

前提:顺序表以创立

代码如下:

void Insert Elem(Linklist * L,int i.ElemType e)
{
  	int j;
  	Linklist p,s;    //开辟两个指针
  	j=1;
  	while(p && j<i)
  	{
  		p=p->next;		//p指向下个结点
  		j++;
	}
	if(!p || j>i)			//当p!=NULL时 且 j> i
		return ERROR ;
	
	s=( (Linklist) 
	s->data=e;
	s->next=p->next;
	p->next = s;
	
	return Ok;
}



详解

请添加图片描述



通过下标 删除元素

前提:顺序表以创立

代码如下:

status Linklist (Linklist * L,int i,ElemType *e)
{
	int j;
	Linklist p,q;
	p=*L;
	j=1;
	while(p- && j<i)
	{
		p=p->next;
	}
	
	if( ! (p->next) && (j>i))
		return ERROR;
	
	q=p->next ;
	p->next=q->next;
	*e=q->next;
	free(q);
	
	return OK;
}



详解图
请添加图片描述



单链表的整表创立

1.头插法 (类似于栈 先进后出)

前提:顺序表以创立

代码如下:

                // 二级指针 
void Createlist(Linklist *L ,int n)
{
	Linklist p;
	*L = (Linklist)malloc(sizeof(Node));   //动态开辟一个带头结点的单链表
	(*L)->next=NULL;                       //让头结点的头指针指向NULL
	for(int i;i<n;i++)
	{
		p=(Linklist)malloc(sizeof(Node));  //每次循环都动态开辟一块空间
		p->data =i;
		p->next=(*L)->next;
		(*L)->next=p;
	}
}

详解图

在这里插入图片描述





2.尾插法

前提:顺序表以创立

代码如下:

void Createlist(Linklist *L ,int n)
{
	Linklist p,r;
	*L = (Linklist)malloc(sizeof(Node));   //动态开辟一个带头结点的单链表
	r=(*L);                               //让r指向L 即 r=L
	for(int i;i<n;i++)
	{
		p=(Linklist)malloc(sizeof(Node));  //每次循环都动态开辟一块空间
		p->data =i;
		r->next=p;
		r=p;
	}
	r->next =NULL;
}



详解

在这里插入图片描述





单链表的整表删除

前提:顺序表以创立

代码如下:

Status Clearlist(Linklist *L)
{
	Linklist p,d;
	p=(*L)->next;
	while(p)
	{
		d=p->next;
		free(p);
		p=d;
	}
	(*L)->next=NULL;
	return OK;
}

详解
在这里插入图片描述


总结

这是琢磨了一天想出来的因为底子不好不是科班学这个,所以画图好理解一些,如果你不理解可以画画图。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值