有序数组合并
有两个递增数组,第一个数组的大小为 m+n 有m个有效数,第二个数组大小为n,有效数为n.试将两个数组合并到第一个数组,且保持数组一的有序。
看到这个题特别容易想到链表的合并,但是若按照链表的正序方法,时间复杂度为O(m*n),效率太慢
所以应该从后向前插入。时间复杂度为O(m+n)
如下代码,含注释。
#include<iostream>
#include<assert.h>
using namespace std;
#define m 4
#define n 5
void ComOrdArray(int* a1, int* a2, int n1,int n2)
{
assert(a1||a2);//判断是否有效
size_t i = n1 + n2-1; //被放值位置
size_t j = 0; //n1-j为比较位置
while (n2&&(j<n1)) //注意j<n1 当数组一中的数值都被移到后面时,就可跳出,直接进行对应赋值
//防止if (*(a1 + n1 - 1-j) <= *(a2 + n2 - 1))时出错
{
if (*(a1 + n1 - 1-j) <= *(a2 + n2 - 1))//当被插入数大于或等于时,直接插入倒数对应位
{
*(a1 + i) = *(a2 + n2 - 1);
--i;
}
else //else 将数组一的数向后移动
{
while (*(a1 + n1 - 1 - j) > *(a2 + n2 - 1))
{
*(a1 + i) = *(a1 + n1 - 1 - j);
--i;
++j;
}
*(a1 + i) = *(a2 + n2 - 1); //找到插入位置 插入
--i;
}
n2--;
}
for (size_t num = 0; num < n2;num++)
{
*(a1 + num) = *(a2 + num);
}
}
int main()
{
int a[m + n] = {5,6,7,15};
int aa[n] = {2,3,6,8,10};
ComOrdArray(a,aa,m,n);
for (size_t i = 0; i < m + n; ++i)
{
cout << a[i] << " ";
}
return 0;
}
有序链表合并
两个有序链表的合并在合并时需要注意的不多,但是对于链表的析构必须要处理好。将s2插入到s1中,由于在合并时并没有创建新的节点,所以原先s2的结构会有改变,且s1含有所有的s2节点,所以将s2也指向s1,两个链表实际管理的是同一个,所以在析构时要特别注意。
实现代码:
void _ComSortList( List<T> &s2)
{
if (_headlist == NULL)
{
_headlist = s2._headlist;
return;
}
Node* cur1 = _headlist;
Node* cur2 =s2._headlist;
Node* next2 = cur2;
Node* prev1 = NULL;
while (cur2&&cur1)
{
if (cur2->_data > cur1->_data)
{
prev1 = cur1;
cur1 = cur1->_next;
}
else
{
next2 = cur2->_next;
if (prev1 == NULL)
{
_headlist = cur2;
prev1 = cur2;
}
else
prev1->_next = cur2;
cur2->_next = cur1;
cur2 = next2;
}
}
if (cur1 == NULL)
{
prev1->_next = cur2;
}
s2._headlist = _headlist;
_count++;
s2._count--;
}
具体代码:
#include<iostream>
#include<stack>
using namespace std;
template<class T>
class ListNode
{
public:
ListNode(const T &data)
:_data(data)
, _next(NULL)
{}
T _data;
ListNode* _next;
};
template<class T>
class List
{
public:
typedef ListNode<T> Node;
List()
:_headlist(NULL)
,_count(1)
{}
void PushBack(const T& data)
{
Node* tmp = new Node(data);
if (_headlist == NULL)
{
_headlist = tmp;
}
else
{
Node* cur = _headlist;
while (cur->_next)
{
cur = cur->_next;
}
cur->_next = tmp;
}
}
~List()
{
if (_headlist&&_count)
{
delete _headlist;
}
_headlist = NULL;
_count--;
}
void Printf()
{
if (_headlist == NULL)
return;
Node* cur = _headlist;
while (cur)
{
cout << cur->_data << " ";
cur = cur->_next;
}
cout << endl;
}
void RevPrintfList1()//利用stack
{
if (_headlist == NULL)
return;
Node* cur = _headlist;
stack<T> st;
while (cur)
{
st.push(cur->_data);
cur = cur->_next;
}
cout << "the relist is :" << endl;
while (!st.empty())
{
cout << st.top() << " ";
st.pop();
}
cout << endl;
}
void RevPrintfList2()//递归
{
if (_headlist == NULL)
return;
cout << "the relist is :" << endl;
_RevPrintfList2(_headlist);
cout << endl;
}
void _ComSortList( List<T> &s2)
{
if (_headlist == NULL)
{
_headlist = s2._headlist;
return;
}
Node* cur1 = _headlist;
Node* cur2 =s2._headlist;
Node* next2 = cur2;
Node* prev1 = NULL;
while (cur2&&cur1)
{
if (cur2->_data > cur1->_data)
{
prev1 = cur1;
cur1 = cur1->_next;
}
else
{
next2 = cur2->_next;
if (prev1 == NULL)
{
_headlist = cur2;
prev1 = cur2;
}
else
prev1->_next = cur2;
cur2->_next = cur1;
cur2 = next2;
}
}
if (cur1 == NULL)
{
prev1->_next = cur2;
}
s2._headlist = _headlist;
_count++;
s2._count--;
}
private:
void _RevPrintfList2(Node* cur)
{
if (cur == NULL)
return;
_RevPrintfList2(cur->_next);
cout << cur->_data<<" ";
}
Node* _headlist;
int _count;
};
#define n1 4
#define n2 5
void ComSortList()
{
int a1[n1] = { 5, 6, 7, 15 };
int a2[n2] = { 2, 3, 6, 8, 10 };
List<int> s1;
List<int> s2;
for (size_t i = 0; i < n1; ++i)
{
s1.PushBack(a1[i]);
}
s1.Printf();
for (size_t i = 0; i < n2; ++i)
{
s2.PushBack(a2[i]);
}
s2.Printf();
cout << endl;
s1._ComSortList(s2);
s1.Printf();
}