改造一個雙向循環鏈表,使右鏈域保持原來的順序,而左鏈域從小到大順序排列。

本題在之前發佈過,但發現方法略有複雜。本次將更新一下最簡單的思想方法 。點擊查看原題出處

在這裏插入圖片描述

思想:

  1. 改進:不需要對每個結點的左鏈域進行置空初始化,因爲最後還是會重新賦值。只需要對頭結點 L 初始化: L->prior = L;
  2. 原方法:每次選出最小元素,採用尾插法排序,較爲繁瑣,而且指針變量太多。新方法:每次選出最大元素,進行頭插法。這樣代碼更爲簡潔,同樣可以實現從小到大排列

附上全部代碼(運行結果)

//.h文件
#ifndef _LINKLIST_H_
#define _LINKLIST_H_

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

#define OK 1
#define ERROR 0

typedef int Status;
typedef int ELEMTYPE;


typedef struct LNode
{
	ELEMTYPE data;  //數據域
	bool flag;  //標誌位  判斷是否選中爲最大元素
	struct LNode *prior; //前驅
	struct LNode *next; //後繼
}LNode,*LinkList;

Status initLinkList(LinkList &L) //初始化鏈表
{
	L = (LNode *)malloc(sizeof(LNode));
	if (!L)
	{
		cout << "空間不足\n";
		return ERROR;
	}
	L->prior = L->next = L;
}

Status CreateLinkList(LinkList &L)  //尾插法建表 讀文件
{
	fstream file;
	file.open("data.txt",ios::in);
	if (!file)
	{
		cout<<"打開文件失敗\n";
		return ERROR;
	}
	LNode *rear = L;
	while (!file.eof())
	{
		LNode *p = (LNode *)malloc(sizeof(LNode));
		file >> p->data;
		p->flag = false;
		p->next = L;
		L->prior = p;
		p->prior = rear;
		rear->next = p;
		rear = p;
	}
	return OK;
}

int getLength(LinkList L) //獲取鏈表長度
{
	LNode *p = L->next;
	int n = 0;
	while(p != L)
	{
		p = p->next;
		n++;
	}
	return n;
}

void Upgrade_1(LinkList &L)  //左鏈域從小到大
{
	L->prior = L;   //讓左鏈域初始化
	LNode *p,*q;
	for (int i = 1; i <= getLength(L); i++)  //右鏈域循環 每次找出一個最大元素
	{	
		p = L->next;
		ELEMTYPE max = -99999; //足夠小
		while (p != L)
		{	
			if (p->data > max && p->flag == false)
			{
				max = p->data;
				q = p;
			}
			p = p->next;
		}
		q->flag = true;  //若最大元素被選中 則標記true 不再參與下輪比較
		q->prior = L->prior; //頭插法 倒序排列 實現從小到大排列
		L->prior = q;
	}
}

void Upgrade_2(LinkList &L) //左鏈域從大到小
{
	L->prior = L;   //讓左鏈域初始化
	LNode *p,*q;
	for (int i = 1; i <= getLength(L); i++)  //右鏈域循環 每次找出一個最小元素
	{	
		p = L->next;
		ELEMTYPE min = 99999; //足夠小
		while (p != L)
		{	
			if (p->data < min && p->flag == false)
			{
				min = p->data;
				q = p;
			}
			p = p->next;
		}
		q->flag = true;  //若最大元素被選中 則標記true 不再參與下輪比較
		q->prior = L->prior; //頭插法 倒序排列 實現從大到小排列
		L->prior = q;
	}
}

void visitRlink(LinkList L)  //右鏈域遍歷
{
	LNode *p = L->next;
	while (p != L)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

void visitLlink(LinkList L) //左鏈域遍歷
{
	LNode *p = L->prior;
	while (p != L)
	{
		cout << p->data << " ";
		p = p->prior;
	}
	cout << endl;
}
#endif

//.cpp文件
#include "stdafx.h"
#include "LinkList.h"

int _tmain(int argc, _TCHAR* argv[])
{
	LinkList L;  //雙循環鏈表
	initLinkList(L); //初始化鏈表
	CreateLinkList(L);  //建表
	Upgrade_1(L); 
	cout << "右鏈域(正常順序):";
	visitRlink(L);
	cout << "左鏈域(從小到大):";
	visitLlink(L);
	initLinkList(L);
	CreateLinkList(L);
	Upgrade_2(L);
	cout << "左鏈域(從大到小):";
	visitLlink(L);
	return 0;
}

運行結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章