线性表
1.线性表-动态分配的顺序存储结构
#define LIST_INTSIZE 100 //线性表初始分配量
#define LIST_INCREMENT 10 //线性表分配增量
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量,以sizeof(ElemType)为单位
}SqList;
动态分配语句
L.elem=(ElemType*)malloc(sizeof(ElemType)*LIST_INCREMENT)
顺序表操作
1. 插入
bool ListInsert (SqList &L,int i,ElemType e)//第i位置插入元素e
{
if (L.length>=listsize||i<1||i>length+1) return false; //插入失败
for(int j=L.length;j>=i;j--) //i位置及之后元素后移
L.elem[j]=L.elem[j-1];
L.elem[i-1]=e;
L.length++;//线性表长+1
return true;//插入成功
}
2. 删除
bool ListDelete(SqList &L,int i, ElemType &e)//删除表L第i个位置,e记录所删
{
if(L.length==0||i<1||i>L.length) return false;//删除失败
e=L.elem[i-1];//记录e
for(int j=i;j<L.length;j++)//位置之后元素前移
L.elem[j-1]=L.elem[j];
L.length--;
return true;// 删除成功
}
- 顺序查找(按值查找)
int LocateElem(SqList L,ElemType e)//表L中查找e元素并返回位置i
{
int i;
for(i=0;i<L.length;i++)
if(L.elem[i]==e) return i;//返回位置i
return 0;//查找失败
}
2.线性表-单链表存储结构
//线性表的单链表存储结构
typedef struct LNode{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode, *LinkList;
2.1建立单链表
- 头插法(将新节点s插入到当前链表的表头L)
void CreateLinkList1(LinkList &L,int n)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode)); //创建头结点
L->next=NULL;//初始为空表
for(int i=0;i<n;i++){
sacnf(“%d”,&x);
s=(LinkList)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
}
return L;
}
- 尾插发(将新节点插入当前链表的表尾,需增加一表尾指针r)
void CreateLinkList2(LinkList &L,int n)
{
Lnode *s,*r;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL; //申空表
r=L;//用r指向表尾
for(int i=0;i<n;i++){
scanf("%d",&x);
s=(LinkList)malloc(sizeof(LNode));
s->data=x;
r->next=s; //r结点之后插入元素x
r=s; //r指向新的表尾节点
}
r->next=NULL; //尾结点置空
return L;
}
2.2查找结点
- 按序号找
LNode *GetElem(LinkList L,int i){
//顺着next往下,找到第i结点为止
int j=1; //计数
LNode *p=L->next;//头结点指针赋值给p
if(i==0)
return L;
if(i<1)
return NULL;
while(p&&j<i){
p=p->next;
j++;
}
return p;
}
- 按值查找
LNode *LocateElm(LinkList L,ElemType e){
LNode *p=L->next;
while(p=!NULL && p->data!=e)
p=p-next;
return p;
}
2.3插入表节点
p结点后插入s(找到前驱,s指向后,前驱指向s)
p=GetElem(L,i-1); //查找插入位置的前驱结点
s->next=p->next;
p->next=s;
S结点前插到p结点前(先后插一节点,然后前后结点值互换)
//先后插一节点
s->next=p->next;
p->next=s;
//前后结点值互换
temp=p->data;
p->data=s->data;
s->data=temp;
2.4删除结点
查找删除–O(n)
(遍历查找p
前驱,并改变前驱p的next指向,跳过p)
p=GetElem(L,i-1); //找删除结点的前驱结点p
q=p->next; //新建一结点q来存储 结点p的后继
p->next=q->next;//结点p的后继变成:结点q(结点p的后继)的后继
free(q); //释放删掉的p
直接删除–O(1)(不适合删最后一个)
(将后继的值赋给p
后,删除p
的后继 )
q=p->next;
p->data=p->next-data; //和后继交换数据
p->next=q->next; //将p指向它后继p的后继
free(q) //释放后继
3.循环链表
循环单链表判空:L->next==L
(头节点指向自己)
循环双链表判断*p为尾结点:p->next==L
(其next
指向头结点)
循环双链表判空:头结点的prior
和next
都等于L
4.双向链表
结构类型
typedef struct DNode{
ElemType data; //数据域
struct DNode *prior, *next; //前驱和后继指针
}DNode, *DNlinklist;
插入操作
在p指针所指结点之后插入结点*s
//顺序不唯一
s->next=p->next;
p->next->prior=s;
s->prior=p;
p->next=s;
删除操作
删除结点*p的后继结点*q
p->next=q->next; //p的后继,指向它后继q的后继
q->next->prior=p; //q后继的前驱,指向q的前驱
free(q)
5.静态链表
结构体
#define MaxSiz 50
typedef struct{
//
ElemType data; //存数据元素
int next; // 下一数据元素的下标
}SLinkList[MaxSize];