算法设计题
问题描述
8.设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同。
算法分析
此题的关键点在于:通过遍历链表能够定位待删除元素的下边界和上边界,即可找到第一个值大于mink的结点和第一个值大于等于maxk的结点。
算法步骤
1.查找第一个值大于mink的结点,用q指向该结点,pre指向该节点的前驱结点。
2.继续向下遍历链表,查找第一个值大于等于maxk的结点,用p指向该结点。
3.修改下边界前驱结点的指针域,使其指向上边界(pre->next=p)。
4.依次释放待删除结点的空间。
算法描述
主要代码
void DeleteMinMax(LinkList &L,int mink,int maxk)
{
//删除递增有序链表L中值大于mink且小于maxk的所有元素
LinkList pre;
LinkList p=L->next; //p指向首元结点
while(p&&p->data<=mink) //查找第一个值大于mink的结点
{
pre=p; //pre指向前驱结点
p=p->next;
}
while(p&&p->data<maxk) //查找第一个值大于等于maxk的结点
{
p=p->next;
}
LinkList q=pre->next;
pre->next=p; //修改待删除节点的指针
while(q!=p) //依次释放待删除结点的空间
{
LinkList s=q->next;
delete q;
q=s;
}
}
完整代码
//******************************数据结构-第二章线性表-算法设计题8******************************//
#include <stdio.h>
#include <iostream>
#define OK 1
#define ERROR 0
using namespace std;
typedef int Status;
//定义单链表的结构类型
typedef int ElemType;
//------单链表的存储结构-----//
typedef struct LNode
{
ElemType data; //结点的数据域
struct LNode *next; //结点的指针域,指向下一个指针
}LNode,*LinkList; // LNode是结点,LinkList是链表,LinkList为指向结构体LNode的指针类型
//------单链表的初始化-----//
//【算法步骤】//
//1.生成新结点作为头结点,用头指针L指向头结点。
//2.头结点的指针域置空。
Status InitList(LinkList &L)
{
//构造一个空的单链表L
L=new LNode; //生成新结点作为头结点,用头指针L指向头结点 或L=(LinkList)malloc(sizeof(LNode))
L->next=NULL; //头结点的指针域置空
return OK;
}
//------后插法创建单链表-----//
//【算法步骤】//
//1.创建一个只有头结点的空链表。
//2.尾指针r初始化,指向头结点。
//3.根据创建链表包括的元素个数n,循环n次执行以下操作:
//生成一个新结点*P;
//输入元素值赋给新结点*p的数据域;
//将新结点*p插入到尾结点*r之后;
//尾指针r指向新的尾结点*p。
void CreateList_R(LinkList &L,int n)
{
//正位序输入n个元素的值,建立带表头结点的单链表L
L=new LNode; //或L=(LinkList)malloc(sizeof(LNode))
L->next=NULL; //先建立一个带头结点的空链表
LinkList r=L; //尾指针r指向头结点
for(int i=0;i<n;++i)
{
LinkList p=new LNode; //生成新结点*p
cin>>p->data; //输入元素值赋给新结点*p的数据域
p->next=NULL;
r->next=p; //将新结点*p插入到尾结点*r之后
r=p; //r指向新的尾结点*p
}
}
//------单链表的插入-----//
//【算法步骤】//
//将值为e的新结点插入到表的第i个结点的位置上,即插入到结点ai-1与ai之间,具体插入过程如图所示,步骤如下:
//1.查找结点ai-1并由指针p指向该结点。
//2.生成一个新结点*s。
//3.将新结点*s的数据域置为e。
//4.将新结点*s的指针域指向结点ai。
//5.将结点*p的指针域指向新结点*s。
Status ListInsert(LinkList &L,int i,ElemType e)
{
//在带头结点的单链表L中第i个位置插入值为e的新结点
LinkList p=L;
int j=0;
while(p && (j<i-1))
{
p=p->next; //查找第i-1个结点,p指向该结点
++j;
}
if(!p||j>i-1) return ERROR; //i>n+1或者i<1
LinkList s=new LNode; //生成新结点*s
s->data=e; //将结点*s的数据域置为e
s->next=p->next;//将结点*s的指针域指向结点ai
p->next=s; //将结点*p的指针域指向结点*s
return OK;
}
//------删除递增有序链表L中值大于mink且小于maxk的所有元素-----//
//【算法步骤】//
//1.查找第一个值大于mink的结点,用q指向该结点,pre指向该节点的前驱结点。
//2.继续向下遍历链表,查找第一个值大于等于maxk的结点,用p指向该结点。
//3.修改下边界前驱结点的指针域,使其指向上边界(pre->next=p)。
//4.依次释放待删除结点的空间。
void DeleteMinMax(LinkList &L,int mink,int maxk)
{
//删除递增有序链表L中值大于mink且小于maxk的所有元素
LinkList pre;
LinkList p=L->next; //p指向首元结点
while(p&&p->data<=mink) //查找第一个值大于mink的结点
{
pre=p; //pre指向前驱结点
p=p->next;
}
while(p&&p->data<maxk) //查找第一个值大于等于maxk的结点
{
p=p->next;
}
LinkList q=pre->next;
pre->next=p; //修改待删除节点的指针
while(q!=p) //依次释放待删除结点的空间
{
LinkList s=q->next;
delete q;
q=s;
}
}
//------打印单链表函数-----//
void PrintList(LinkList L)
{
printf("当前单链表中所有元素为:");
for(LinkList p=L->next;p!=NULL;p=p->next)
{
if(p->next==NULL)
printf("%d",p->data);
else
printf("%d->",p->data);
}
printf("\n");
}
//------创建单链表函数------//
void CreateList(LinkList &L)
{
int n;
printf("请输入要创建的单链表L的长度:");
scanf("%d",&n);
printf("请依次输入%d个数(空格隔开):",n);
CreateList_R(L,n);
printf("单链表L创建成功!\n");
PrintList(L);
}
//------单链表插入函数------//
void InsertList(LinkList &L)
{
int i,e;
printf("请输入要插入的位置:");
scanf("%d",&i);
printf("请输入要在第%d个位置插入的数据元素:",i);
scanf("%d",&e);
bool flag=ListInsert(L,i,e);
if(flag)
{
printf("元素%d插入单链表成功!\n", e);
PrintList(L);
}
else
{
printf("元素%d插入单链表失败!\n",e);
}
}
//------删除递增有序链表L中值大于mink且小于maxk的所有元素------//
void DeleteMinMaxList(LinkList L,int mink,int maxk)
{
DeleteMinMax(L,2,6);
printf("删除递增有序链表L中值大于mink且小于maxk的所有元素后的数据元素:\n");
PrintList(L);
}
//------主函数-----//
int main()
{
int n,mink,maxk;
LinkList L;
InitList(L);
CreateList(L);
DeleteMinMaxList(L,mink,maxk);
}
运行结果
请输入要创建的单链表L的长度:8
请依次输入8个数(空格隔开):1 2 3 4 5 6 7 8
单链表L创建成功!
当前单链表中所有元素为:1->2->3->4->5->6->7->8
删除递增有序链表L中值大于mink且小于maxk的所有元素后的数据元素:
当前单链表中所有元素为:1->2->6->7->8
--------------------------------
Process exited after 13.63 seconds with return value 0
请按任意键继续. . .