有关线性表的一些算法题

1.设计一个时间复杂度为O(n)的算法,实现将数组A[n]中所有元素循环右移k个位置

举例:a[] = {1,2,3,4,5},循环右移1位后 a[] = {5,1,2,3,4};

首先,我们可能想到的算法是,先将数组的后k个元素保存到一个临时数组中,然后将前n-k个元素右移k个位置.然后将临时数组的元素复制到元素的前k个位置.

实现:

template 
void MoveArrayAdditional(T array[], int nLen, int k)
{
	// 后k个元素移到临时数组,然后将前n-k个元素循环右移k位,再将临时数组元素放到数组前面
	int other[k];
	int m = k;
	for (int i = 0; i
这个算法的时间复杂度符合要求,但是需要额外的k个存储单元.

我们可以换个角度解决这个问题.把这个问题看作把数组ab转换为数组ba;先将a逆置得到a^b,再将b逆置得到a^b^,最后将这个a^b^逆置得到(a^b^)^ = ba.于是得到:

template 
void MoveArray(T array[], int nStart, int nEnd)
{
	while (nStart < nEnd)
	{
		T temp = array[nStart];
		array[nStart] = array[nEnd];
		array[nEnd] = temp;
		nStart++;
		nEnd--;
	}
}
emplate 
void MoveArrayK(T array[], int nLen, int k)
{
	MoveArray(array, 0, nLen-1);
	MoveArray(array, 0, k-1);
	MoveArray(array, k, nLen-1);
}
可以用翻转左右手来形象的形容这个问题.

2.已知数组A[n]的元素为整型,设计算法将其调整为左右两部分,左边所有元素为奇数,右边所有元素为偶数.

void DevisionOddAndEven(int array[], int nLen)
{
	// 设置两个标志位,分别指示数组头和尾;
	// 判断头元素是否为奇数
	// 是:组头标记前移;
	// 不是:将头元素与尾元素互换,尾元素前移.
	// 当头元素和尾元素标记重合,停止
	int nStart = 0;
	int nEnd = nLen - 1;
	while (nStart != nEnd)
	{
		if (array[nStart]%2 != 0)
		{
			nStart++;
		}else
		{
			int temp = array[nStart];
			array[nStart] = array[nEnd];
			array[nEnd] = temp;
			nEnd--;
		}
	}
}
3.给定两个链表的头结点,判断是否相交

template 
bool TwoLinkIsIntersect(Node* pHead1, Node* pHead2)
{
	if (pHead1 == NULL || pHead2 == NULL)
	{
		return false;
	}
	// 1.两个链表相交,它们的尾结点一定相同;所以分别找到两个链表的尾结点,判断值是否相等.
	Node* rear1 = pHead1;
	Node* rear2 = pHead2;
	while (rear1->pNextNode != NULL || rear2->pNextNode != NULL)
	{
		if (rear1->pNextNode != NULL)
		{
			rear1 = rear1->pNextNode;
		}
		if (rear2->pNextNode != NULL)
		{
			rear2 = rear2->pNextNode;
		}
	}
	if (*rear1 == *rear2)
	{
		return true;
	}
	return false;
}







你可能感兴趣的:(数据结构和算法)