定义
#define MaxSize 10
typedef struct{
Elemtype data[MaxSize];
int length;
}SqList;
初始化
void InitList(SqList &L){
for(int i = 0; i < MaxSize; i++) L.data[i] = 0;
L.length = 0;
}
int main()
{
SqList L; //声明
InitList(L); //初始化
}
#define InitSize 10 //初始长度
typedef struct{
ElemType *data; //指示动态分配数组的指针
int MaxSize; //最大容量
int length; //当前长度
}SeqList;
初始化
void InitList(SeqList &L){
L.data = (int *)malloc(InitSize * sizeof(int)); //设int型
L.length = 0;
L.MaxSize = InitSize;
}
增加动态数组的长度
//malloc 动态扩展顺序表的最大容量,最后需要free函数释放原区域
void IncreaseSize(SeqList &L, int len){
int *p = L.data; //用p指向原来的数组的起始地址
L.data = (int *)malloc((L.MaxSize + len)*sizeof(int));
for(int i = 0; i < L.length; i++) L.data[i] = p[i]; //数据复制到新区域,时间开销大
L.MaxSize = L.Maxsize + len;
free(p); //释放原来的内存空间
}
//将元素e插入到L的第i个位置 1 <= i <= length+1
bool ListInsert(SqList &L,int i,int e){
if(i<1 || i > L.length+1) return false;
if(L.length >= MaxSize) return false;
for(int j = L.length; j >= i; j--) L.data[j] = L.data[j-1]; //从最后一个元素开始后移一位
L.data[i-1] = e;
L.length++;
return true;
}
//删除表L中第i个位置的元素,并用e返回 1 <= i <= length
bool ListDelete(SqList &L, int i, int &e){
if(i<1 || i > L.length) return false;
e = L.data[i-1];
for(int j = i; j < L.length; j++) L.data[j-1] = L.data[j]; //从第i+1位置开始,向前移动
L.length --;
return true;
}
tips: 添加时移动元素是从最后一个元素开始后移,删除时是从第i+1个位置开始前移
int GetElem(SqList L, int i){
return L.data[i-1]
}
int LocateElem(SqList L,int e){
for(int i = 0; i < L.length; i++)
if(L.data[i] == e) return i+1;
return 0;
}
定义
typedef struct LNode{
ElemType data;
struct Node *next;
}LNode, *LinkList;
tips: 使用LNode*
用于强调是结点,使用LinkList
用于强调是单链表
//不带头结点
bool InitList(LinkList &L){
L = NULL; //用此判空
return true;
}
//带头结点
bool InitList(LinkList &L){
L = (LNode*)malloc(sizeof(LNode));
if(L == NULL) return false; //分配失败
L->next = NULL; //用此判空
return true;
}
//有头结点,对于在第一个位置插入不需特殊处理,因为0号结点就是头结点,相当于在头结点后插
bool ListInsert(LinkList &L,int i,ElemType e){
if(i<1) return false;
LNode *p; //指向当前扫描到的结点
int j =0; //当前p指向的是第几个结点
p = L; //p指向头结点
while(p != NULL && j < i-1){ //找到第i-1个结点,即插入位置的前一个结点
p = p->next;
j++;
}
if(p == NULL) return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
s -> data = e;
s -> next = p -> next;
p -> next = s;
return true;
}
//无头结点,当在第一个位置插入需要特判
bool ListInsert(LinkList &L,int i,ElemType e){
if(i<1) return false;
if(i == 1)
{
LNode *s = (LNode *)malloc(sizeof(LNode));
s -> data = e;
s -> next = L;
L = s; //头指针指向第一个结点
return true;
}
LNode *p; //指向当前扫描到的结点
int j = 1; //当前p指向的是第几个结点
p = L; //p指向第一个结点
while(p != NULL && j < i-1){ //找到第i-1个结点,即插入位置的前一个结点
p = p->next;
j++;
}
if(p == NULL) return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
s -> data = e;
s -> next = p -> next;
p -> next = s;
return true;
}
bool InsertNextNode(LNode *p, ElemType e){
LNode *s = (LNode *)malloc(sizeof(LNode));
s -> data = e;
s -> next = p -> next;
p -> next = s;
return true;
}
//法1:引入头指针,从头指针遍历找到p的前驱结点q,再对q后插
//法2:偷天换日,实际是尾插,但将其data替换
bool InsertPriorNode(LNode *p, ElemType e){
LNode *s = (LNode *)malloc(sizeof(LNode));
s -> next = p -> next;
p -> next = s;
s -> data = p -> data;
p -> data = e;
return true;
}
需要找到前驱节点
bool ListDelete(LinkList &L,int i,ElemType &e){
if(i<1) return false;
LNode *p; //指向当前扫描到的结点
int j =0; //当前p指向的是第几个结点
p = L; //p指向头结点
while(p != NULL && j < i-1){ //找到第i-1个结点,
p = p->next;
j++;
}
if(p == NULL) return false;
if(p->next == NULL) return false;
LNode *q = p -> next;
e = q -> data;
p -> next = q -> next;
free(q);
return true;
}
//法1:引入头指针,从头指针遍历找到p的前驱结点q
//法2:偷天换日
bool DeleteNod(LNode *p){
if(p == NULL) return false;
LNode *q = p->next;
p -> data = q -> data; //如果p是最后一个节点,那么q不存在,只能从表头开始寻找p的前驱
p -> next = q -> next;
free(q);
return true;
}
LNode * GetElem(LinkList L,int i){
if(i<0) return false;
LNode *p; //指向当前扫描到的结点
int j =0; //当前p指向的是第几个结点
p = L; //p指向头结点
while(p != NULL && j < i){ //找到第i个结点
p = p->next;
j++;
}
return p;
}
LNode * LocateElem(LinkList L,ElemType e){
LNode *p = L->next;
while(p != NULL && p->data != e)
p = p->next;
return p;
}
相当于对尾结点的后插,则可以设立一个表尾指针,每次插入一个结点后将其修改。
LinkList List_TailInsert(LinkList &L){
int x;
L = (LinkList)malloc(sizeof(LNode)); //建立头结点
LNode *s,*r = L; //r为表尾指针
cin >> x;
while(x!=9999) //设立一个特殊值表示结束
{
s = (LNode *)malloc(sizeof(LNode));
s -> data = x;
r -> next = s;
r = s; //r指向新的表尾
cin >> x;
}
r -> next = NULL;
return L;
}
相当于对头结点的后插
LinkList List_HeadInsert(LinkList &L){
int x;
L = (LinkList)malloc(sizeof(LNode)); //建立头结点
L -> next = NULL;
LNode *s;
cin >> x;
while(x!=9999) //设立一个特殊值表示结束
{
s = (LNode *)malloc(sizeof(LNode));
s -> data = x;
s -> next = L -> next;
L -> next = s;
cin >> x;
}
return L;
}
//给定一个L,如何逆置
LinkList List_HeadInsert(LinkList L,LinkList &L2){
int x;
L2 = (LinkList)malloc(sizeof(LNode)); //建立头结点
L2 -> next = NULL;
LNode *s;
LNode *p = L->next;
while(p != NULL){
x = p -> data;
s = (LNode *)malloc(sizeof(LNode));
s -> data = x;
s -> next = L2 -> next;
L2 -> next = s;
}
return L2;
}
```
定义
typedef struct LNode{
ElemType data;
struct Node *prior,*next;
}LNode, *DLinkList;
L->prior = NULL;
L->next = NULL;
//p结点后插入s结点
s->next = p->next;
if(p->next != NULL) p->next->prior = s; //如果p有后继
p->next = s;
s->prior = p;
//删除p结点的后继结点
DNode *q = p->next;
p->next = q->next;
if(q->next != NULL) q->next->prior = p;
free(q);
//后向
while(p!=NULL) p=p->next;
//前向
while(p!=NULL) p=p->prior;
//前向(跳过头结点)
while(p->prior!=NULL) p=p->prior;
L->next = L; //判空
判断p是否为表尾结点
p->next == L;
L->prior = L;
L->next = L; //判空
判断p是否为表尾结点
p->next == L;
插入删除时,不用判断
//p后插入s
s->next = p->next;
p->next->prior = s;
p->next = s;
s->prior = p;
//删除p结点的后继结点
DNode *q = p->next;
p->next = q->next;
q->next->prior = p;
free(q);
定义
typedef struct{
ElemType data;
int next; //下一个元素的数组下标
}SLinkList[MaxSize];
SLinkList a;
a[0] = -1;