编程基础: 数据结构 算法
//顺序储存结构的结构代码:
#define MAXSIZE 20//储存空间的起始分配量
typedef int ElemType;//ElemType类型根据实际类型而定,这里假设是int
typedef struct{
ElemType data[MAXSIZE];//数组储存元素,最大值为MAXSIZE
int length;/线性表当前长度;
}SqList;
//顺序存储结构需要三个属性:
//1存储空间的起始位置:数组data,它的存储位置就是存储空间的储存位置;
//2最大储存量:MAXSIZE
//3线性表当前长度
在顺序储存结构中第i个数据元素ai的储存位置与ai的储存位置的关系
LOC(ai)=LOC(ai)+(i-1)*c;
Stattus ListInsert(SqList *L,int i,ElemType e){
int k;
if(L->length==MAXSIZE)
return ERROR;
if(i<1||i>L->length+1)
return ERROR;
if(i<=L->length)
{
for(k=L->length-1;k>=i-1;k--)
L->data[k+1]=L->data[k];//将要插入位置后数据元素向后移动一位;
}
L->data[i-1]=e;
L->length++;
return OK;
}
时间复杂度 O(n);
Status ListDlete(SqList *L,int i,ElemType *e)
{
int k;
if(L->length==0)
return ERROR;
if(i<1||i>L->length)
return ERROR;
*e=L->data[i-1];
if(ilength)
{
for(k=i;klength;k++)
L->data[k-1]=L->data[k];
}
L->length--;
return OK;
}
时间复杂度O(n)
//线性表的单链表的链式储存结构
typedef struct Node//结点的定义
{
ElemType data;
struct Node *next;
} Node;
typedof struct Node *LinkList;//定义单链表
Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p;
p=L->next;//指向L的第一个节点
j=1;//j为计数器
while(p&&jnext;
++j;
}
if(!p||j>i)
return ERROR;/第i个节点不存在
*e =p->data;
return OK;
}
时间复杂度O(n)
Status ListInsert(LinkeList *L,int i,ElemType e){
int j;
LinkList p,s;
p=*L;
j=1;
while(p&&jnext;
++j;
}
if(!p||j>1)
return ERROR;
s=(LinkList)malloc(sizeof(Node));
s->data=e;
s->next=p->next;//注意赋值 的顺序,先赋值s->next然后再赋值p->next;
p->next=s;
return OK;
}
时间复杂度O(n);
Status ListDelete(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,q;
p=*L;
j=1;
while(p->next &&jnext;
++j;
}
if(!(p->next)||j>i)
return ERROR;//第i个结点不存在
q=p->next;
p->next=q->next;
*e=q->data;//将q结点的数据给*e
free(q);
return OK;
}
时间复杂度:O(n);
头插法:
void CreateListHead(LinkList *L,int n)
{
LinkList p;
int i;
srand(time(0));//初始化随机数种子;
*L=(LinkList)malloc(sizeof (Node));
(*L)->next=NULL;//先建立一个带头结点的单链表
for(i=0;idata=rand()%100+1;
p->next=(*L)->next;
(*L)->next=p;//插入到表头
}
}
尾插法
void CreateListTail(LinkList *L,int n)
{
LinkList p,r;
int i;
srand(time(0));
*L=(LinkList)malloc(sizeof(Node));
r=*L;
for (int i=0;idata=rand()%100+1;
r-next=p;
r=p;
}
r->next=NULL;//表示当前表结束
}
Status ClearList(LinkList *L)
{
LinkList p,q;
p=(*L)->next;
while(P)
{
q=p->next;//先保存p->next然后再释放p;
free(p);
p=q;
}
(*L)->next=NULL;//头结点的指针域为空
return OK;
}
//数组第一个和最后一个元素特殊处理,不存数据,第一个元素的cur存备用链表的第一个结点的小标,最后一个元素的cur存第一个有元素的下标,相当于头结点
#define MAXSIZE 1000
typedef struct
{
ElemType data;
int cur;//游标Cursor,为0时表示无指向
}Component,StaticLinkList[MAXSIZE];
//将一维数组space中各分量链成一备用链表
//space[0].cur为头指针,“0”表示空指针
Status InitList(StaticLinkList space)
{
int i;
for(i=0;i
int Malloc_SLL(StaticLinkList space)
{
int i=space[0].cur;
if(space[0].cur)
space[0].cur=sapce[i].cur;//由于要拿出一个分量来使用了,所以我们就得把它的下一个分量来做备用
return i;//返回分配的结点下标
}
//在L中第i个元素之前插入新的数据元素e
Status ListInsert(StaticLinkList L,int i,ElemType e)
{
int j,k,l;
k=MAXSIZE-1;//k首先是最后一个元素的下标
if(i<1||i>ListLength(L)+1)
return ERROR;
j=Malloc_SSL(L);//获得空闲分量的下标
if(j)
{
L(j).data=e;
for(l=1;l<=i-1;i++)//找到第i个元素之前的位置
k=L[k].cur;
L[j].cur=L[k].cur;
L[k].cur=j;
return OK;
}
return ERROR;
}
//删除在L中的第i个元素
Status ListDelele(StaticLinkList L,int i)
{
int j,k;
if(i<1||i>ListLength(L))
return ERROR;
k=MAXSIZE-1;
for(j=1;j<=i-1;j++)
k=L[k].cur;
j=L[k].cur;//获得第i个元素在数组中的下标
L[k].cur=L[j].cur;//将欲删除的元素的cur值赋给它的前一个元素;
Free_SSL(L,j);
return OK;
}
void Free_SSL(StaticLinkList space ,int k)
{
space[k].cur=space[0].cur;//使删除的这个位置成为第一个优先空位
space[0].cur=k;
}
int ListLength(StaticLinkList L)
{
int j=0;
int i=L[MAXSIZE-1].cur;
while(i)
{
i=L[i].cur;
j++;
}
return j;
}
单循环链表:将单链表中的终端结点的指针端由空指针改为指向头结点,单循环链表简称循环链表
双向链表:在单链表的每个结点中再设置一个指向其前驱结点的指针(双向链表也可以是循环链表)
typedef struct DulNode
{
ElemType data;
struct DulNode *prior;//直接前驱指针
struct DulNode *next;
}DulNode,*DuLLinkList;
双向链表的插入操作:
//在p和p->next之间插入结点e
s->prior=p;
s->next=p->next;
p->next->prior=s;
p->next=s;
双向链表的删除操作:
//删除p结点
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
线性表分为顺序储存结构和链式储存结构
链式储存结构又分为单链表,静态链表,循环链表,双向链表