一、线性链表
参考书:《数据结构(C语言)》–严蔚敏等编著,清华大学出版社。
1、链式存储结构
线性表的链式存储结构特点是用一组任意的存储单元存储线性表的数据元素,与顺序存储结构的区别在于这组存储单元可以是连续的,也可以是不连续的,并且存储方式为顺序存取,顺序结构是随机存取。在优缺点上有以下特点:
优点:
1、节点空间可以动态申请或释放;
2、数据元素按照逻辑次序靠指针指示,插入与删除无需移动大量元素;
缺点:
1、存储密度太小(<1),指针域还需额外的存储空间;
线性链表也可分为有头链表和无头链表:
无头链表如下:
有头链表如下:
在链表中设置头结点的好处:
1、便于首元节点的处理:首元节点的地址保存在了头结点的指针域中,所以在链表中的第一位置上的操作和其他位置上的一致,无须进行特殊处理;
2、头结点便于空表和非空表的统一处理,无论链表是否为空,头指针都指向头结点的非空指针;
2、线性链表的建立与插入操作
相关步骤:
在第3个位置之前插入3元素步骤:
(1)查找第i-1的位置,使p指向i-1的位置;
(2)创建q节点,存放e元素(3),将p的next赋给q的next,使p节点连接至3;如下:
(3)再将p的next指向q就可以连成串了;
相关代码:
#include "stdio.h"
#include "stdlib.h"
//#include "LinkList.h"
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define MAX_LIST_SIZE 100
#define LISTINCREMENT 10
typedef int Status;
typedef int ElemType;
typedef struct LNode {
ElemType data; //数据域(信息域)
struct LNode *next; //指针域
} LNode, *LinkList;
Status CreateList_L(LinkList &L,int n);
//构造有n个元素的有头结点的链表L
Status CreateList_L(LinkList &L,int n) {
LinkList p,q;
int i;
L = (LinkList) malloc (sizeof(LNode));
L->next=NULL;
q=L; //起初为L(头)---->NULL
for(i=1; i<=n; i++) {
p = (LinkList) malloc (sizeof(LNode)); //定义p节点存储值
//scanf("%d",p->data);
p->data=i; //将i值赋值给p
q->next=p; //q的next指向p
p->next=NULL; //p的next指向NULL
q=q->next; //q后移
}
return OK;
}
Status ListInsert_L(LinkList &L,int i,ElemType e);
//在链表的第i个位置之前插入元素e的值
Status ListInsert_L(LinkList &L,int i,ElemType e) {
LinkList p,q;
p=L;
int j=0; //建立一个j变量,后面需要使用判断合法性
while(p && j<i-1) { //定位到i-1的位置
p = p->next; //p后移直到指向i-1的位置
++j;
}
if(!p || j>i-1) return ERROR; //表明i的值小于1或者大于表长+1
q = (LinkList) malloc (sizeof(LNode)); //生成新节点q
q->data=e;
q->next=p->next; //p的next给q的next
p->next=q; //将p的next指向q,连成一串
return OK;
}
Status ListDisPlay_L(LNode *L);
//打印链表
Status ListDisPlay_L(LNode *L) {
LNode *p;
p=L->next; //p指向头结点
if(p == NULL) exit(OVERFLOW);
else {
while(p != NULL) {
if(p->next != NULL)
printf("%d,",p->data);
else{
printf("%d",p->data);
}
p=p->next; //p指针后移
}
}
}
int main(void) {
LinkList L;
CreateList_L(L,5); //这里为了测试,采用1,2,3,4,5的链表,可根据自身而定
int i,e; //插入位置及元素
scanf("%d %d",&i,&e);
if(ListInsert_L(L,i,e))
ListDisPlay_L(L);
else
printf("插入位置非法\n");
return 0;
}
/*
使用单链表存储结构,实现顺序表的插入操作,给出插入位置,
输出插入后线性表的元素。如果插入位置不合法则输出:
插入位置非法。
初始化线性表为:1,2,3,4,5
如:
输入:3 3 输出:1,2,3,3,4,5
输入:-4 3 输出:插入位置非法
*/
实现:
初始链表: 1,2,3,4,5
插入:3 3
插入:-1 2