第二章:线性表
知识点:
1、编写程序实现对顺序表逆置
void Invert(seqList *L,int length)
{
int temp;
int i;
for(i=0;i<length/2;i++)
{
temp = L->data[i]; //交换
L->data[i] = L->data[length-i-1];
L-data[length-i-1] = temp;
}
}
2、编写程序将有序递增的单链表中的数据值在a到b之间的元素删除
void DeleteAb(LinkList &L,int a,int b)
{
LNode *P = L->next; //默认带头结点
LNode *Pre = L; //删除结点的前驱结点
while(P!=NULL)
{
if(P->data<a)
{
Pre = p; //Pre为第一次出现元素a的前驱
p=p->next;
}
else if(P->data>=a&&p->data<=b)
{
p=p-next; //p指向首次大于b停止
}
else
Pre->next=p; //即删除a-b之间的元素
}
Pre->next=p; //指向表尾NULL,表尾元素小于等于b
}
3、编写程序删除单链表中所有关键字值为x的元素
void DeleteX(LinkList &L,int x)
{
LNode *p=L->next;
LNode *pre=L; //p的前驱
while(P!=NULL)
{
if(p->data==x)
{
LNode *temp = P;
pre->next = temp->next;
p=p->next;
free(temp);
}
else
{
pre=p;
p=p->next; //遍历
}
}
}
4、编写程序实现对单链表的逆置
void Reverse(LinkList &L)
{
LNode *p=L->next;
L->next=NULL;
LNode *r=L->next;
while(P!=NULL)
{
r=p->next; //保留后继结点,防止断链
p->next=L->next;
L->next=p;
p=r; //头插法实现逆置
}
}
5、编写程序实现将数据域值最小的元素放置在单链表的最前面
void swap(LinkList &L)
{
//算法思想:交换链表的两个元素,关键在保留目标元素指针和前驱指针
LNode *pre,*p,*minPre,min;
min = L->next;
minPre = NULL;
p = L->next;
Pre = L;
while(p!=NULL)
{
if(p->data<min->data)
{
min = p;
minPre = pre;
}
pre = p;
p = p->next;
}
if(min!=L->next)
{
//若不是在最前面再交换
minPre->next=min->next;
min->next=L->next;
L->next=min;
}
}
6、编写程序将两个有序递增的单链表合并为一个有序递增的单链表
LinkList Merger(LinkList A,LinkList B)
{
//A,B都是有序递增的单链表,合并成一个递增单链表C
LNode *p=A->next,*q=B->next;
LinkList C=(LinkList)malloc(sizeof(LNode));
if(C==NULL)
return NULL;
LNode *r=C; //遍历C
while(p!=NULL&&q!=NULL)
{
LNode *s=(LinkList)malloc(sizeof(LNode));
if(p->data<=p->data)
{
s->data=p->data;
p=p->next;
}
else
{
s->data=q->data;
q=q->next;
}
r->next=s;
r=s;
}
if(p!=NULL)
r->next=p;
else
r->next=q;
free(A);
free(B);
return C;
}
7、以顺序表A、B表示的集合,编写程序求A、B的交集
int[] intersection(int A[],int B[])
{
int i=0,j=0;
int C[Max];
int k=0; //k遍历新建顺序表C
for(i=0;i<Max;i++)
for(j=0;j<Max;j++)
{
if(A[i]==B[j])
{
C[k++]=A[i];
break;
}
}
return C;
}
8、以单链表A、B表示两个集合,编写程序求A、B的交集
LinkList intersection(LinkList &A,LinkList &B)
{
LNode *p=A->next,*q=B->next;
LinkList C=(LinkList)malloc(sizeof(LNode));
if(C==NULL)
return NULL;
LNode *r=C; //遍历C
while(p!=NULL)
{
while(q!=NULL)
{
if(p->data==q->data)
{
LNode *s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
break; //找到一处就寻找下一处交集
}
else
q=q->next;
}
p=p->next;
}
return C;
}
9、顺序表的Insert函数,在表满时仅提示出错信息,请重写此函数,在表满时是表的长度增长1倍,并将新元素插入顺序表。
bool Insert(SeqList &L,int i,int x)
{
int j;
if(i<-1||i>L->n-1) //判断下标i是否越界
return false;
if(L->n==L->maxLength)
{ //增加动态顺序表的长度
int *p=L->data;
L->data=(int *)malloc((L->maxLength*2)*sizeof(int));
for(int k=0;k<maxLength;k++)
{
L->data[k]=p->data[k]; //将数据复制到新区域
}
L->maxLength=L->maxLength*2; //最大长度增加1倍
free(p); //释放原来内存空间
}
for(j=L->n-1;j>i;j--)
L->data[j+1]=L->data[j];
L->data[i+1]=x;
L->n=L->n+1;
return true;
}
10、编写程序实现将数据域值最大的元素放置在单链表的最后面
void swap(LinkList &L)
{
//算法思想:交换链表的两个元素,关键在保留目标元素指针和前驱指针
LNode *pre,*p,*maxPre,max;
max = L->next;
maxPre = NULL;
p = L->next;
Pre = L;
while(p!=NULL) //循环结束后p为NULL,pre为最后一个结点
{
if(p->data>max->data)
{
max = p;
maxPre = pre;
}
pre = p;
p = p->next;
}
if(max!=pre->next)
{
//若不是在最后面再交换
maxPre->next=max->next;
max->next=pre->next;
pre->next=max;
}
}
相关考法:
-
线性表
——概要 线性表是有限的
——考察简答题,尽可能描述思想,模式化-
1、顺序表
-
1、线性表的顺序存储结构是一种随机存取的存储结构
-
2、顺序表的动态分配,申请增加分配m个空间,需要加上之前满元素的空间n,即申请m+n连续的空间,再将之前n个元素复制过来,释放之前指向n的指针
-
-
2、链表
-
考点
-
1、判断删除,插入删除哪个正确
-
2、思考一些操作的时间复杂度是否为O(n),O(1),经常出现在循环链表表头、表尾插入删除操作,选择最优数据结构,P41,t24
-
3、链式每个元素不一定连续,但结点内必然连续
-
4、单循环链表带头结点,判空条件需要注意,L->next=L,即头结点的指针域与L的值相等
-
-
存储
-
不带头结点的
-
注意第一个元素的处理
-
-
带头结点
-
-
操作
-
1、插入
-
重点🔑:前插 某个值可用(暴力法)
-
-
2、头插法
-
不带头结点的头插法可以理解为某一指定结点的前插,实现该算法
-
实现一个链表原地逆置 思路:只需要通过头结点与第一个结点做文章就行,第一个结点会成为最后一个结点,指针结束时指向NULL
-
-
-
-
扩展
-
循环|双链表
-
双链表
-
-
注意边界表尾部的指针域设置 避免空指针的操作
-
-
-
-
静态链表
-
P42、t31、t33
-
-
-
-