系列文章目录
第二话 数据结构之线性表
文章目录
- 一、线性表的基本操作步骤
- 1.存储结构
- 2.基本操作
- 3.实现运用
- 二、线性表的插入
- 三、线性表的删除
- 四、总结
前言
为了克服顺序表的缺点,可以采用链式方式存储线性表。链式存储是最常用的动态存储方式,它不需要用地址连续存储的存储单元来实现,而是通过“链”建立起数据元素之间的逻辑关系,对线性表的插入,删除不需要移动数据元素。
一、线性表的基本操作步骤
如下:
1、定义存储结构--链式存储
#include <stdio.h>
#include <stdlib.h>
typedef int Elemtype;
typedef struct node{
Elemtype date;
struct node *next;
}LinkList;
//让链表的名称为LinkList
2、将线性表初始化
LinkList *init_list()
{
LinkList *L;
L = (LinkList*)malloc(sizeof(LinkList));//为链表申请一块空间
L->next = NULL;//首先让链表指为空;
return L;
}
3、将线性表输入数据
1.头插法
得到的单链表的逻辑顺序与输入元素顺序相反
LinkList *createlist(LinkList *L)
{
//链表尾插法
LinkList *p;
Elemtype x;
printf("输入链表元素,输入-1表示结束\n");
scanf("%d",&x);
while(x!=-1){
p = (LinkList*)malloc(sizeof(LinkList));//初始化一个空链表
p->date = x;
p->next = L->next;//将结点插入到表头
L->next = p;
scanf("%d",&x);
}
return L;
}
2.尾插法
得到的单链表的逻辑顺序与输入元素顺序相同
LinkList *createlist(LinkList *L)
{
//链表尾插法
LinkList *p;
Elemtype x;
printf("输入链表元素,输入-1表示结束\n");
scanf("%d",&x);
while(x!=-1){
p = (LinkList*)malloc(sizeof(LinkList));//初始化一个空链表
p->date = x;
L->next = p;//将结点插入到表头
L = p;
scanf("%d",&x);
}
p->next = NULL;
return L;
}
头插法与尾插法的小区别:
1.两者在插入的方式是不一样的
2.头差法没有p->next = NULL
4、将线性表数据输出
void OutLinklist(LinkList *L)
{
LinkList *p;
p = L->next;//将表头赋予给链表;
while(p!=NULL){
printf("%5d",p->date);
p = p->next;//将结点指向下一个
}
printf("\n");
}
5、在主函数中实现调用
为了方便插入与删除,这里使用尾插法演示
int main()
{
LinkList *L1;
L1 = init_list();
createlist(L1);
OutLinklist(L1);
return 0;
}
二、线性表的插入
1.演示图
由于链表没有长度,所以用while来寻找位置
1、将新建的链表指向头的后一个:s->next = p->next
2、将头指针指向新建的链表:p->next = s
void pushLinklist(LinkList *L,int i,Elemtype x)
{
LinkList *p,*s;
p = L;
int j = 0;
while(p!=NULL&&j<i-1){
p = p->next;
j++;
}//寻找要插入的位置
s = (LinkList*)malloc(sizeof(LinkList));
s->date = x;
s->next = p->next;//第一步
p->next = s;//第二步
}
int main()
{
LinkList *L1;
L1 = init_list();
createlist(L1);
pushLinklist(L1,2,50);//在第二个位置插入数字50
OutLinklist(L1);
return 0;
}
三、线性表的删除
1、演示图
1、将下一个单元赋于给新建的表格s,s = p->next
2、将p的结点指向s后面的单元,p->next = s->next
3、将创建的单元s释放掉,free(s)
void popLinklist(LinkList *L,int i)
{
int j = 0;
LinkList *p,*s;
p = L;
while(p!=NULL&&j<i-1){
p = p->next;
j++;
}//寻找要删除的位置
s = (LinkList*)malloc(sizeof(LinkList));
s = p->next;//第一步将p的下一个赋给s
p->next = s->next;//将p结点指向s的下一个
free(s);//释放s
}
int main()
{
LinkList *L1;
L1 = init_list();
createlist(L1);
popLinklist(L1,2);//将第二个数据删除
OutLinklist(L1);
return 0;
}
四、总结
顺序表和链表的存储结构各有优缺点。在实际应用中究竟选用何种存储结构要根据具体的要求和性质。
一、空间的考虑
线性表要事先对MAXSIZE要有合适的设定,防止浪费或溢出。因此对线性表的长度或存储规模难以估计时,不宜采用顺序表。链表不用事先估计存储规模,但链表的存储密度较低。
二、时间的考虑
顺序表访问任意数据元素的时间复杂度为O(1),链表访问任意元素的时间复杂度为O(n),在访问情况来看,线性表优于链表。
三、语言环境的考虑
顺序表容易实现,任何高级程序设计语言都i有数组类型,链表是基于指针的。相对来讲数组简单些,这也是设计者考虑的一个因素。
总之、两种存储结构各有优缺点,选择哪一种存储结构由实际问题的主要因素决定。