一段合併多個有序數組並且升序輸出數組元素的C++代碼

今天心情由特別爛轉變爲特別好!!!所以決定寫一篇,是實驗室裏做東西用到的~~

標題起的不好哈~以下代碼的意思就是:合併多個有序數組,由小到大不重複地輸出裏面的元素值。實現的方法是將這些數組合並建最小堆,每次彈出堆頂。

具體算法:

1、將每個數組的第一個元素保存到堆中,並記錄其來自哪個數組。整理堆。

2、如果堆不爲空且數組沒有遍歷完,彈出堆頂。否則轉5。

3、如果彈出的值等於上一次彈出的值last_data,將該值所在數組的下一個元素讀入堆,整理堆並轉2。否則轉4。

4、將該值輸出,將該值所在數組的下一個元素讀入堆,整理堆並轉2。

5、結束。

C++代碼如下:

定義heap_item類:

class heap_item
{
public:
	int data;
	int array_id;
	heap_item(int d, int i)
	{
		data = d;
		array_id = i;
	}
	heap_item(const heap_item &i)
	{
		data = i.data;
		array_id = i.array_id;
	}
};
定義multi_heap類:

class multi_heap
{
private:
        vector<heap_item> h;
        vector<vector<int> *> header;
        vector<int> ptr;
        int vec_num;
        int last_data;
public:
        multi_heap(){vec_num=0;last_data=-1;}
        ~multi_heap(){}
        void AddVector(vector<int> *v);
        int PopMin(void);
        void MakeHeap(void);
        static bool cmp(heap_item a, heap_item b)
        {
              return a.data>b.data;
        }
};
multi_heap成員函數的實現:

void multi_heap::AddVector(vector<int> *v)
{
	header.push_back(v);
	ptr.push_back(0);
	vec_num++;
}

int multi_heap::PopMin(void)
{
	if (!vec_num)
		return -1;	// 表示所有vector都掃描完

	int temp_ptr;
	int curr_id;
	
	// 刪除重複item, 加入新item
	while (!h.empty() && h[0].data == last_data)
	{
		curr_id = h[0].array_id;
		temp_ptr = ptr[curr_id]++;
		pop_heap(h.begin(),h.end(), cmp);
		h.pop_back();
		if (temp_ptr != header[curr_id]->size())
		{
            heap_item item((*header[curr_id])[temp_ptr], curr_id);
			h.push_back(item);
			push_heap(h.begin(), h.end(), cmp);
		}
		else
			vec_num--;	// 當一個vector掃描結束,vector總數減少1
	}
	// pop最小item的值
	if (!h.empty())
	{
		last_data = h[0].data;
		curr_id = h[0].array_id;
		temp_ptr = ptr[curr_id]++;
		pop_heap(h.begin(), h.end(), cmp);
		h.pop_back();
		if (temp_ptr != header[curr_id]->size())
		{
            heap_item item((*header[curr_id])[temp_ptr], curr_id);
			h.push_back(item);
			push_heap(h.begin(), h.end(), cmp);
		}
		else
			vec_num--;	// 當一個vector掃描結束,vector總數減少1
		return last_data;
	}
	else
		return -1;	// 完成
}

// add in the first item of all vectors
void multi_heap::MakeHeap(void)
{
	if (vec_num)
	{
		for (int i=0; i<vec_num; i++)
		{
            heap_item item((*header[i])[0],i);
			h.push_back(item);
			ptr[i] = 1;
		}
		make_heap(h.begin(), h.end(), cmp);
	}
}

主函數:

int main(void)
{
    int arr1[] = {1,2,4,9,10};
    int arr2[] = {1,5,6,7,10,11,17};
    int arr3[] = {3,4,5,7,8,9,13,14,15,16};
    vector<int> v1(arr1,arr1+5);
    vector<int> v2(arr2,arr2+7);
    vector<int> v3(arr3,arr3+10);
    
    multi_heap my_heap;
    my_heap.AddVector(&v1);
    my_heap.AddVector(&v2);
    my_heap.AddVector(&v3);
    
	my_heap.MakeHeap();
    int data = my_heap.PopMin();
    while (data != -1)
    {
          cout << data << " ";
          data = my_heap.PopMin();
    }
    
    system("pause");
    return 0;
}

用到的頭文件是:

<iostream>

<vector>

<algorithm>

運行輸出爲:1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17

PS:編碼風格不太好請見諒哈~害羞

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