1-线性表

线性表

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;// 删除成功
}
  1. 顺序查找(按值查找)
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建立单链表

  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;
}
  1. 尾插发(将新节点插入当前链表的表尾,需增加一表尾指针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查找结点

  1. 按序号找
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;
}
  1. 按值查找
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指向头结点)

循环双链表判空:头结点的priornext都等于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];

猜你喜欢

转载自blog.csdn.net/qq_41962612/article/details/115082324