王道考研 数据结构之线性表
线性表基本知识点
思维导图
线性表代码
一、顺序表
1. 顺序表定义
-
静态定义
#define MaxSize 50 typedef struct{ ElemType data[MaxSize]; int length; }SqList;
-
动态定义
#define InitSize 100 typedef struct{ ElemType *data; //分配数组的指针 int length,MaxSize; //数组的当前个数和最大容量 }SqList;
//初始动态分配语句 //1.c L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize); //2.c++ L.data = new ElemType[InitSize];
2.顺序表基操
-
插入
bool ListInsert(SqList &L, int i, ElemType e){//顺序表L,插入位置i,插入元素e //1.判断插入的位置是否正确 i的位置在1到长度加一(末尾插)之间 if(i > L.length+1||i < 1) return flase; //2.判断当前存储空间是否满 if(L.length >= MaxSize) return flase; //3.从最后一个元素到插入位置i的元素往后移一位 for(int j = L.length;j >= i;j--) L.data[j] = L.data[j-1]; //4.将插入元素e放进i的位置 L.data[i-1] = e; //5.线性表长度加一 L.length++; return true; }
插入位置和数组下标要区别开来
位置是1到数组长度;可以插入的位置为1到数组长度+1,此时的加一为末尾最后一个位置,此位置也可以插入。
数组下标是0到数组长度-1;
插入位置为i ,这个位置在数组中为:L.data[i-1] -
删除
bool ListDelete(SqList &L, int i, ElemType &e){ //顺序表L,删除位置i,删除元素e //1.判断删除位置是否合法 if(i < 1 || i > L.length) return flase; //2.将删除位置元素存起来 e = L.data[i-1]; //3.将删除位置后一个元素到最后一个元素往前移一位,直接覆盖前面元素 for(int j = i;j < L.length;j++) L.data[j-1]=L.data[j]; //4.长度减一 L.length--; return true; }
-
按值查找(顺序查找)
int LocateElem(SqList L,ElemType e){//顺序表L,查找元素e //1.顺序查找,找到返回位序 for(int i = 0;i < L.length;i++){ if(L.data[i]==e) return i+1 } //2.未找到,查找失败 return 0; }
二、单链表
1. 单链表定义
typedef struct LNode{
ElemType data;//数据域
struct LNode *next;//指针域
}LNode, *LinkList
2.单链表基操
-
头插法建立表
生成链表中结点的次序与输入数据的顺序相反LinkList CreateListHead(LinkList &L){//单链表L //从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素 LNode *s; int x;//表内元素类型 //1.创建头结点 L=(LinkList)malloc(sizeof(LNode)); //2.初始化为空链表 L->next = NULL; //3.循环输入 while(scanf("%d",&x) != EOF){ //4.创建新结点 s=(LNode*)malloc(sizeof(LNode)); //5.将新结点插入链表中,L为头指针 s->data = x; s->next = L->next; L->next = s; } return L; }
-
尾插法建立表
LinkList CreateListTail(LinkList &L){//单链表L //从表尾到表头正向建立单链表L,每次均在表尾插入元素 int x;//表内元素类型 //1.创建尾结点 L=(LinkList)malloc(sizeof(LNode)); //2.将表尾指针指向结点 LNode *s,*r = L; //3.循环输入 while(scanf("%d",&x) != EOF){ //4.创建新结点 s=(LNode*)malloc(sizeof(LNode)); //5.将新结点插入链表中 s->data = x; r->next = s; r = s;//r指向新的表尾结点 } //6.尾结点指针置空 r->next = NULL; return L; }
-
按序号查找结点值
LNode *GetElem(LinkList L,int i){ //取出单链表L(带头结点)中第i个位置的结点指针 int j = 1; //1.头结点赋值给p LNode *p = L->next; //2.i为0,返回头结点 if(i==0) return L; //3.i位置不合法,返回空 if(i<1) return NULL; //4.从第一个结点开始遍历,一直找到第i个结点 while(p&&j<i){ p = p->next; j++; } //5.返回第i个结点的指针;如果i大于表长 p=null 直接返回p即可 return p; }
-
按值查找表结点
LNode *LocateElem(LinkList L,ElemType e){ //取出单链表L(带头结点)中数据域等于e的结点指针,否则返回NULL //1.头结点赋值给p LNode *p = L->next; //2.从第一个结点开始查找数据域等于e的结点 while(p!=NULL&&p->next!=e){ p = p->next; } //5.找到返回改指针结点,否则返回NULL return p; }
-
插入结点(两种)
//一、前插 //1.查找插入结点的前驱位置 p = GetElem(L,i-1); //2.在节点p后插入结点s s->next = p->next; p->next = s; //二、后插(在单链表插入中通常采用后插操作,前插均可转换成后插--前插操作之后交换数据域) //1.在节点p后插入结点s s->next = p->next;//修改指针域 p->next = s; //2.交换数据域 temp = p->data; p->data = s->data; s->data = temp;
-
删除结点
//删除给定结点后一结点*q
//1.查找删除结点的前驱位置
p = GetElem(L,i-1);
//2.令q指向被删除结点
q = p->next;
//3.将*q结点从链中断开
p->next = q->next;
//4.释放q结点
free(q);
//删除所给结点*p
//1.令q指向*p的后继结点
q = p->next;
//2.和后继结点交换数据域
p->data = p->next->data;
//3.将q结点从链中断开
p->next = q->next;
//4.释放q结点
free(q);
三、双链表
1. 双链表节点定义
typedef struct DNode{
ElemType data;//数据域
struct DNode *prior,*next;//前驱和后继指针
}DNode,*DLinkList;
2.双链表基操
-
插入
//将*s结点插入到*p之后 s->next = p->next; p->next->prior = s; s->prior = p; p->next = s;//1.2步必须在4步之前,否则*p后继结点的指针会丢掉
-
删除
//删除*p的后继结点*q p->next = q->next; q->next->prior = p; free(q);
四、静态链表
静态链表结构类型描述
#define MaxSize 50//静态链表的最大长度
typedef struct{
ElemType data;//存储数据元素
int next;//下一个元素的数组下标
}SLinkList[MaxSize];
静态表的插入删除操作与动态链表相同,只需要修改指针,不需要移动元素
合集:
数据结构之线性表
数据结构之栈与队列
数据结构之串
数据结构之树与二叉树
数据结构之图
数据结构之查找
数据结构之排序