顺序表2021-05-23
注意:每一个代码请对照教材相应的图,这样方便理解
严格对照教材
顺序表结构定义
const int Maxsiez=100;
typedef struct
{
DataTpye data[Maxsize];
int length;
} SeqList;//顺序表类型名为SeqList
SeqList L;
线性表的基本运算在顺序表上的实现
1 插入,时间复杂度为O(n)
void InsertSeqlist(SeqList L,DataType x,int i)
{ //将元素x插入到顺序表L的第i个数据元素之前
if (L.length==Maxsize) exit("表已满");
if (i<1 || i>L.length+1) exit("位置错");
for (j=L.length;j>=i;j--)
L.data[j]=L.data[j-1];//注意:由最后一个元素开始以此往后移动一个单元,所以是--
L.data[i-1]=x;//[i-1]表示i在数组中的实际位置
}
2 删除,时间复杂度为O(n)
void DeleteSeqlist(SeqList L,int i)
{
if (i<1 || i>L.length)//检查了这个元素i是否存在和有没有空表的情况
exit ("非法位置");
for (j=i;j<L.length;j++)
L.data[j-1]=L.data[j];//i+1个元素开始依次向左移动一个单元
L.length--;
}
3 定位,时间复杂度为O(n)
void LocateSeqlist(SeqList L,DataType x)
{
int i=0;//注意第一元素是序号是1,但在数组中的下标是0,要从数组中的第一个元素依次向后查找,因此赋0给i
while ((i<L.length) && (L.data[i] != x))
i++;
if (i<L.length)
return i+1;//这时,找到x并且不会超出表长,由于定位返回的是结点序号,因此i又加1
else return 0;
}
4 求表长,时间复杂度为O(1)
L.length
5 读表元素,L中的i元素,时间复杂度为O(1)
L.data[i-1]
单链表的类型定义
typedef struct node
{
DataType data;
struct node* next;
} Node,*LinkList;
线性表的基本运算在单链表上的实现
1 初始化
LinkList InitateLinkList()
{ //建立带有头结点的空链表
LinkList head;//头指针
head=malloc(sizeof(Node));//头结点
head->next=NULL;
return head;
}
2 求表长
int LengthLinklist(LinkList head)
{ //求单链表表head的长度
Node * p=head;
int cnt=0;
while (p->next != NULL)//判断是否为尾结点
{
p=p->next;
cnt++;
}
return cnt;//返回表长
}
3 读表元素
Node * GetLinklist(LinkList head,int i)
//在单链表head中查找第i个元素结点。若找到,则返回指向该结点的指针;否则返回NULL
{
Node *p;
p=head->next//p指向首结点
int c=1;
while ((c<i) && (p != NULL))
{
p=p->next;
c++;
}
if (i==c)
return p;
else return NULL;
}
4 定位
int LocateLinklist(LinkList head,DataType x)
//求表head中的第一个值等于x的结点的序号,若不存在这种结点,返回结果为0
{
Node * p=head;
p=p->next;
int i=0;
while (p != NULL && p->data != x)
{
i++;
p=p->next;
}
if (p != NULL)
return i+!;
else return 0;
}
5 插入
void InsertLinklist(LinkList head,DataType x,int i)
{ //将表head的第i个数据元素结点之前插入一个以x为值的新结点
Node *p,*q;
if (i==1)
q=head;
else q=GetLinklist(head,i-1);
if (q==NULL)
exit ("找不到插入的位置");
else
{
p=malloc(sizeof(Node));p->data=x;//生成新结点
p->next=q->next;
q->next=p;
}
}
6 删除
void DeleteLinklist(LinkList head,int i)
{ //删除表head的第i个结点
Node *p,*q;
if (i==1)
q=head;
else q=GetLinklist(head,i-1);
if (q != NULL && q->next != NULL)
{
p=q->next;
q->next=p->next;
free(p);
}
else exit("找不到要删除的结点");
}
小结:插入和删除都要事先找到第i-1个结点
其它运算在单链表上的实现
1 建表
尾插法
方法一:
LinkList CreatLinklist()
{ //通过调用InitiateLinklist和InsertLinklist实现建表算法。假定0是输入结束标志
Linklist head;
int x,i;
head=InitiateLinklist();
i=1;
scanf("&d",&x);
while (x != 0)
{
InsertLinklist(head,x,i);
i++;
scanf("%d",&x);
}
return head;
}
方法二:
LinkList CreatLinklist2()
{ //q是一个Linklist类型的变量,用来指示链入位置
Linklist head;
Node *q,*t;
int x;
head=malloc(sizeof(Node));
q=head;
scanf("&d",&x);
while (x != 0)
{
t=malloc(sizeof(Node));t->data=x;//生成一个新结点
q->next=t;
q=t;
scanf("%d",&x);
}
q->next=NULL;
return head;
}
头插法建表
LinkList CreatLinklist3()
{
Linklist head;
Node *q;
int x;
head=malloc(sizeof(Node));
head->next=NULL;
scanf("&d",&x);
while (x)
{
p=malloc(sizeof(Node));
p->data=x;
p-next=head->next;
head->next=p;
scanf("%d",&x);
}
return head;
}
2 删除重复结点
void PurgeLinklist(Linklist head)
{
Node *p,*q,*r;
q=head->next;
while (q != NULL)
{
p=q;
while(p->next != NULL)
if (p-next->data == q->data)
{
r=p->next;
p->next=r->next;
//移出结点*(p-next),p->next指向原来*(p->next)的后继结点
free(r);
}
else p=p->next;
q=q->next;
}
}
双向循环链表
struct dbnode
{
Datatype data;
struct dbnode *prior,*next;
}
typedef struct dbnode *dbpointer;
typedef dbpointer DLinkList;
基本运算
1 删除
p-prior->next=p->next;
p->next->prior=p->prior;
free(p);
2 插入
t->prior=p;
t->next=p->next;
p->next->prior=t;
p->next=t;
posted on
浙公网安备 33010602011771号