目录
一、线性表的顺序储存结构:顺序表
首先进行自定义:
typedef struct
{
Elemtype data[MAXSIZE]; //这里的Elemtype是自定义的数据类型
int long; //定义表长
}Sqlist; //这个结构体类型的名字叫做Sqlist
初始化顺序表:
Status Initlist(Sqlist *L) //这里的Status是函数的类型
{
L->length=0;
return OK;
}
这里补充一下:
Sqlist L;
L.data[0]; //表示第一个元素
L.data[L.length-1];//表示最后一个元素
L.length; //代表表长
遍历操作:
Status Listtraverse(Sqlist L)
{
int i;
for(i=0;i<L.length;i++)
printf("%d\n",L.data[i]);
printf("\n");
return OK;
}
判断是否为空:
Status Listempty(Sqlist L)
{
if(L.length==0)
{
return TRUE;
}
else
{
return FALSE;
}
}
清空操作:
Status Clearlist(Sqlist *L) //初始条件是表存在
{
L->length=0;
return OK;
}
求表长:
int Listlength(Sqlist L)
{
return L.length;
}
按位查找:并且用e返回第i个位置的值
Status Getelem(Sqlist L,int i,Elemtype *e)
{
if(L.length==0||i>L.length||i<1)
{
return FALSE;
}
else
{
*e=L.data[i-1];
return OK;
}
}
按值查找:返回表中值为e的位序
int Locatelist(Sqlist L,int i,Elemtype e)
{
if(L.length==0||i>=L.length)
{
return 0;
}
for(i=0;i<L.length;i++)
{
if(L.data[i]==e)
{
break;
}
}
return i+1;//data[0]是第一个元素,所以位序要加一
}
插入操作:在第i个位置插入元素e,此时表长要加一
Status Listinsert(Sqlist *L,int i,Elemtype e)
{
int k;
if(L->length==MAXSIZE||i<1||i>L->length+1)
return ERROR;
if(i<=L->lehgth) //插入位置不在表尾
{
for(k=L->length-1;k>=i-1;k--)
{
L->data[k+1]=L->data[k]; //将所有i后边的元素后移一位
}
}
L->data[i-1]=e; //在第i个元素前面插入e
L->length++; //表长加一
return OK;
}
删除操作:表存在则删除第i个元素,并且用e返回其值
Status Listdelete(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 (i<L->length) //如果删除元素不是最后位置
{
for(k=i;k<L->length;k++) //将删除位置的所有后继元素前移
L->data[k-1]=L->data[k];
}
L->length--;
return OK;
}
将两个顺序表整合:
void unionL(SqList *La,SqList Lb)
{
int La_len,Lb_len,i;
ElemType e; //声明与La和Lb相同的数据元素e
La_len=ListLength(*La); //求线性表的长度
Lb_len=ListLength(Lb);
for (i=1;i<=Lb_len;i++) //我们对表b进行遍历,将它的每一个值取出来如果a中没有则插入到a里面
{
GetElem(Lb,i,&e); //取Lb中第i个数据元素赋给e
if (!LocateElem(*La,e)) //La中不存在与之相同的数据元素
ListInsert(La,++La_len,e); //则将其插入到表a中
}
}
二、单链表
单链表的创建:
typedef struct Node //定义新的类型名Node
{
ElemType data; //数据域
struct Node *next; //指针域
}Node;
typedef struct Node *LinkList; //定义LinkList
这里使用LinkList 类型的指针变量来表示链表的头节点,并通过 next 指针将多个节点链接在一起形成链表结构。
初始化操作:
Status Ininlist(Linklist *L) //这里的L是指向Linklist的指针,就是指向指针的指针
{
*L=(Linklist)malloc(sizeof(Node))
if(!(*L)) // 存储分配失败
return ERROR;
(*L)->next=NULL; //指针域为空,设置空指针,表示链表中只有一个结点
return OK;
}
判断表空:
Status ListEmpty(LinkList L)
{
if(L->next)
return FALSE;
else
return TRUE;
}
清空操作:
Status Clearlist(Linklist *L)
{
Linklist p,q;
p=(*L)->next;//p指向头节点
while(p)
{
q=p->next;
free(p);
p=q;
}
(*L)->next=NULL;
return OK;
}
求表长:
int ListLength(LinkList L) //LinkList L表示传入的链表头节点
{
int i=0;
LinkList p=L->next; // p指向首元结点
while(p) //结点非空则进入循环
{
i++; //i就是个计数器,非空则自加
p=p->next; //指针p后移
}
return i; //i的值即链表长度,也就是元素个数
}
按位查找:
Status GetElem(LinkList L,int i,ElemType *e)//ElemType *e表示要返回的元素值的指针
{
int j=1; //j是计数器,i是我们需要查找的位置
LinkList p; //声明一结点p
p = L->next; //让p指向链表L的首元结点
while (p && j<i) //p不为空或者计数器j还没有等于i时,循环继续
{
p = p->next; //让p指向下一个结点
++j;
} //通过逐步遍历找到所需位置的元素
if ( !p || j>i ) //如果结点为空或者链表中不存在第i个位置
return ERROR; //第i个元素不存在
*e = p->data; //取第i个元素的数据
return OK;
}
按值查找:
int LocateElem(LinkList L,ElemType e)
{
int i=0;
LinkList p=L->next; //p指向首元结点
while(p)
{
i++;
if(p->data==e) //找到这样的数据元素
return i;
p=p->next;
}
return 0;
}
插入操作:
Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,s; //p和s是两个链表结点指针
p = *L; //链表的头结点赋值给变量p
j = 1;
while (p && j < i) //寻找第i个结点,通过循环遍历找到i
{
p = p->next; //指针p之间后移
++j;
}
if (!p || j > i)
return ERROR; // 第i个元素不存在
s = (LinkList)malloc(sizeof(Node)); // 生成新结点,为其分配存储空间
s->data = e;
s->next = p->next; //将p的后继结点赋值给s的后继
p->next = s; //将s赋值给p的后继
return OK;
}
删除操作:
Status ListDelete(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,q;
p = *L;
j = 1;
while (p->next && j < i) //遍历寻找第i个元素
{
p = p->next;
++j;
}
if (!(p->next) || j > i)
return ERROR; //第i个元素不存在
q = p->next;
p->next = q->next; //将q的后继赋值给p的后继
*e = q->data; //将q结点中的数据给e
free(q); //让系统回收此结点,释放内存
return OK;
}
遍历操作:
Status ListTraverse(LinkList L)
{
LinkList p=L->next;
while(p)
{
printf("%d\n",p->data);
p=p->next;
}
printf("\n");
return OK;
}
三、总结语:
说白了顺序表就是用数组,链表就是用指针,然后自己定义一堆函数进行调用来实现功能操作。学习数据结构更重要的是先理解然后多练习,多敲代码。
下期再见!