合并k个排序链表(优先级队列的运算符重载或归并算法)

优先级队列要求,当容器的元素类型是类或者结构体时,“<”运算符必须有定义,优先级队列默认情况下就是按“<”运算符来决定元素大小的。
例子如下:

#include<stdio.h>  
#include<functional>  
#include<queue>  
#include<vector>  
using namespace std;
//定义结构,使用运算符重载,自定义优先级1  
struct cmp1 {
	bool operator ()(int &a, int &b) {
		return a>b;//最小值优先  
	}
};
struct cmp2 {
	bool operator ()(int &a, int &b) {
		return a<b;//最大值优先  
	}
};

int a[] = { 14,10,56,7,83,22,36,91,3,47,72,0 };

int main()
{
	priority_queue<int>que;//采用默认优先级构造队列  

	priority_queue<int, vector<int>, cmp1>que1;//最小值优先  
	priority_queue<int, vector<int>, cmp2>que2;//最大值优先  

	priority_queue<int, vector<int>, greater<int> >que3;//注意“>>”会被认为错误,  
														//这是右移运算符,所以这里用空格号隔开  
	priority_queue<int, vector<int>, less<int> >que4;////最大值优先  

	int i;
	for (i = 0; a[i]; i++) {
		que.push(a[i]);
		que1.push(a[i]);
		que2.push(a[i]);
		que3.push(a[i]);
		que4.push(a[i]);
	}
	printf("采用默认优先关系:\n(priority_queue<int>que;)\n");
	printf("Queue 0:\n");
	while (!que.empty()) {
		printf("%3d", que.top());
		que.pop();
	}
	puts("");
	puts("");

	printf("采用结构体自定义优先级方式一:\n(priority_queue<int,vector<int>,cmp>que;)\n");
	printf("Queue 1:\n");
	while (!que1.empty()) {
		printf("%3d", que1.top());
		que1.pop();
	}
	puts("");
	printf("Queue 2:\n");
	while (!que2.empty()) {
		printf("%3d", que2.top());
		que2.pop();
	}
	puts("");
	puts("");
	printf("采用头文件\"functional\"内定义优先级:\n(priority_queue<int,vector<int>,greater<int>/less<int> >que;)\n");
	printf("Queue 3:\n");
	while (!que3.empty()) {
		printf("%3d", que3.top());
		que3.pop();
	}
	puts("");
	printf("Queue 4:\n");
	while (!que4.empty()) {
		printf("%3d", que4.top());
		que4.pop();
	}
	system("pause");
	return 0;
}

还有一种方法:

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

class node {
public:
	int x, y;
	node(int x, int y) :x(x), y(y) {}
	friend bool operator <(const node&a, const node&b) {
		if (a.y == b.y)
			return a.x > b.x;
		else
			return a.y>b.y;
	}
};
//class node {
//public:
//	int x, y;
//	node(int x, int y) :x(x), y(y) {}
//	bool operator <(const node&a) const{
//		if (y == a.y)
//			return x > a.x;
//		else
//		return y>a.y;
//	}
//};
int main() {
	priority_queue<node> q;//优先级队列要求,当容器的元素类型是类或者结构体时,“<”运算符必须有定义,优先级队列默认情况下就是按“<”运算符来决定元素大小的
	q.push(node(1, 5));
	q.push(node(3, 1));
	q.push(node(1, 1));
	q.push(node(3, 2));
	while (!q.empty()) {
		cout << q.top().x << " " << q.top().y << " " << endl;
		q.pop();
	}
	system("pause");
	return 0;
}

接下来看题:
在这里插入图片描述
法1:优先级队列

class Solution {
public:
	struct cmp {  //自定义比较函数,对新的数据类型的<进行重载
		bool operator()(ListNode *a, ListNode *b) {
			return a->val > b->val;
		}
	};

	ListNode* mergeKLists(vector<ListNode*>& lists) {
		priority_queue<ListNode*, vector<ListNode*>, cmp> pri_queue;
		for (auto p : lists)
		{
			if (p != NULL)
				pri_queue.push(p);//压入所有链表的头结点
		}

		ListNode *pHead = new ListNode(-1);
		ListNode *pCur = pHead;
		while (!pri_queue.empty())
		{
			ListNode *top = pri_queue.top(); pri_queue.pop();
			pCur->next = top;
			pCur = pCur->next;
			if (top->next != NULL)
			{
				pri_queue.push(top->next);
			}
		}
		pCur = pHead->next;
		delete pHead;
		pHead = NULL;
		return pCur;

	}
};

法2:归并(思路与合并两个排序链表相同)
相当漂亮的解法!!!

class Solution {
public:
	ListNode* mergeKLists(vector<ListNode*>& lists) {
		if (lists.size() == 0)return NULL;
		return merge(lists, 0, lists.size() - 1);
	}

	ListNode*merge(vector<ListNode*>& lists, int left, int right)//归并
	{
		if (left == right) return lists[left];
		int mid = left + (right - left) / 2;
		ListNode *l1 = merge(lists, left, mid);//[left, mid]的链表合并完成,返回合并后的头结点
		ListNode *l2 = merge(lists, mid + 1, right);//[mid + 1, right]的链表合并完成,返回合并后的头结点
		return mergeTwoLists(l1, l2);

	}
	ListNode* mergeTwoLists(ListNode*p1, ListNode*p2)
	{
		ListNode*t1, *t2;//双指针
		t1 = p1, t2 = p2;
		ListNode*newHead = new ListNode(-1);
		ListNode*t = newHead;
		while (t1 != NULL && t2 != NULL)
		{
			if (t1 != NULL&&t2 != NULL)
			{
				if (t1->val <= t2->val)
				{
					t->next = t1;
					t1 = t1->next;
					t = t->next;

				}
				else
				{
					t->next = t2;
					t2 = t2->next;
					t = t->next;

				}
			}
		}
		if (t1 == NULL)
		{
			t->next = t2;

		}
		else
			t->next = t1;
		return newHead->next;
	}
};

在这里插入图片描述

在这里插入图片描述

发布了212 篇原创文章 · 获赞 4 · 访问量 8793

猜你喜欢

转载自blog.csdn.net/ShenHang_/article/details/104677695