有关线性表的一些算法题

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

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

template <class T>
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 <class T>
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 <class T>
bool TwoLinkIsIntersect(Node<T>* pHead1, Node<T>* 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;
}







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值