线性表之删除节点和交换节点-习题8-9

第1关:删除链表中满足条件的节点

本关任务:编写一个算法, 删除递增有序链表中值大于mink且小于maxk的所有元素的程序。

思路 :遍历链表,满足条件删除该节点,不满足则找下一个

#include<iostream>
#include<fstream>
using namespace std;
#define ERROR 0

typedef struct LNode //定义单链表
{
	int data;
	struct LNode *next;
} LNode, *LinkList;

int num_a, num_b;


void InitList_L(LinkList &L) //创建单链表
{
	L = new LNode;
	L->next = NULL;
}

void input(LinkList &L, int n) //依次往单链表L里输入数据
{
	int i;
	LNode *p, *r;
	r = L;
	while (n --) 
	{
		p = new LNode;
		cin >> p->data;
		p->next = NULL;
		r->next = p;
		r = p;
	}

}

void output(LinkList L) //依次输出单链表里的每个元素
{
	int i = 0;
	LNode *p;
	p = L->next;
	while (p) {
		if (i)
			cout << " ";
		cout << p->data;
		p = p->next;
		i = 1;
	}
}

int DeleteList_L(LinkList &LA, int maxk, int mink) //算法设计6 
{
	//已知单链表LA
	//求LA的最大值 
	//if(LA->next == NULL) return NULL;
	/*******************************Begin******************/
    LinkList p = LA,q = LA -> next;

    while(p && q)
    {
        if(q -> data > mink && q -> data < maxk)
        {
            LinkList t = q;
            p -> next = q -> next;
            q = q -> next;
            delete t;
        }
        else
        {
            p = p -> next;
            q = q -> next;
        }
    }
    /*******************************End******************/
} 

int main() 
{
	LinkList La, Lb, Lc;
	
	scanf("%d", &num_a);
	
	InitList_L(La); //La表的创建
	input(La, num_a); //依次往单链表La里输入数据

	int maxk, mink;
	scanf("%d %d", &mink, &maxk);
	DeleteList_L(La, maxk, mink); 
	
	output(La);

	return 0;
}

第2关:交换双链表中的节点

本关任务:编写一个算法, 交换双链表中指定的节点。

思路 : 要交换的两个节点记作 p,q,p 的前驱 记作 l,q 的后继记作 r,再更新 l,q,p,r 的前驱和后继就行了。

#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型

struct Point {
	int x;//x坐标 
	int y;//y坐标 
};
typedef struct DuLNode {
	Point data; //数据域
	struct DuLNode *prior; //直接前驱
	struct DuLNode *next; //直接后继
} DuLNode, *DuLinkList;


int length;

Status InitDuList_L(DuLinkList &L) {
	//构造一个空的双向链表L
	L = new DuLNode; //生成新结点作为头结点,用头指针L指向头结点
	L->next = NULL; //头结点的指针域置空
	L->prior = NULL;
	return OK;
}

DuLNode *GetElemP_DuL(DuLinkList L, int i) {
	//在带头结点的双向链表L中查找第i个元素,返回结点的地址
	int j;
	DuLinkList p;
	p = L->next;
	j = 1; //初始化,p指向第一个结点,j为计数器
	while (j < i && p) { //顺链域向后扫描,直到p指向第i个元素或p为空
		p = p->next;
		++j;
	}
	if (!p || j > i)
		return NULL; //第i个元素不存在
	return p;
} //GetElemP_DuL

Status ListInsert_DuL(DuLinkList &L, int i, Point e) { //算法2.13 双向链表的插入
	//在带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长+1
	DuLinkList s, p;
	if (!(p = GetElemP_DuL(L, i))) //在L中确定第i个元素的位置指针p
		return ERROR; //p为NULL时,第i个元素不存在
	if (i == 1) {//在双向链表的第一个元素上插入
		s = new DuLNode; //生成新结点s
		s->data = e; //将结点s数据置为e
		DuLinkList p = L->next;
		L->next = s;
		s->prior = L;
		s->next = p;//将结点*s插入L中
		p->prior = s;
		++length;
	} else if (i == length) {//在双向链表的最后一个元素上插入
		s = new DuLNode; //生成新结点s
		s->data = e; //将结点s数据置为e
		DuLinkList p = L;
		while (p->next)
			p = p->next;//将LinkList p指向双向链表结尾
		p->next = s;
		s->prior = p;//将结点*s插入到p的后面,插入到L中
		s->next = NULL;
		++length;
	} else {
		s = new DuLNode; //生成新结点*s
		s->data = e; //将结点*s数据域置为e
		s->prior = p->prior; //将结点*s插入L中,此步对应图2.20① 
		p->prior->next = s; //对应图2.20②
		s->next = p; //对应图2.20③
		p->prior = s; //对应图2.20④
		++length;
	}
	return OK;
} //ListInsert_DuL

Status ListDelete_DuL(DuLinkList &L, int i) { //算法2.14 双向链表的删除
	//删除带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长
	DuLinkList p;
	if (!(p = GetElemP_DuL(L, i))) //在L中确定第i个元素的位置指针p
		return ERROR; //p为NULL时,第i个元素不存在
	if (i == 1)//删除双向链表的第一个元素
		L = L->next;
	else if (i == length) {//删除双向链表的最后一个元素
		p->prior->next = NULL;
		delete p;
		--length;
		return OK;
	} else {
		p->prior->next = p->next; //修改被删结点的前驱结点的后继指针,对应图2.21①
		p->next->prior = p->prior; //修改被删结点的后继结点的前驱指针,对应图2.21②
		delete p; //释放被删结点的空间 
		--length;
		return OK;
	}
}//ListDelete_DuL

void CreateDuList_L(DuLinkList &L, int m) 
{
	//正位序输入n个元素的值,建立带表头结点的双向链表L,同时建立前驱指针
	DuLinkList r, p;
	L = new DuLNode;
	L->next = NULL; //先建立一个带头结点的空链表
	r = L;//尾指针r指向头结点
	length = 0;
	
	while (m --) 
	{
		p = new DuLNode; //生成新结点
		cin >> p->data.x >> p->data.y; //输入元素值
		p->next = NULL;
		r->next = p; //插入到表尾
		r = p; //r指向新的尾结点
		p->prior = L->prior; //插入到表头
		L->prior = p;
		length++;
	}

} //CreateDuList_L
void Exchange(DuLinkList p)
{
	/******************************Begin************************/
    DuLinkList q = p -> prior,l = q -> prior,r = p -> next;

    l -> next = p,p -> next = q,q -> next = r;
    r -> prior = q,q -> prior = p,p -> prior = l;

    /*****************************End**************************/
}
void output(DuLinkList L)
{
	//双向链表的输出
	DuLinkList p = L->next;
	while (p) 
	{
		cout << p->data.x << " " <<  p->data.y << endl;
		p = p->next;
	}
}
int main() 
{
	int a;

	DuLinkList L, p;
    
	InitDuList_L(L); 
			
	int n;
	cin >> n;
	CreateDuList_L(L, n);

	scanf("%d", &a);
	p = GetElemP_DuL(L, a);
	
	Exchange(p);
	
	output(L); 		
 	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值