1.仅有头指针,查找输出倒数第k个元素。
基本思想是设置两个指针p、q均指向链表的第一个数据结点,p沿着链表移动,q先不动,设置一个计数器count初值为0,count随着p的移动而增加,当count的值为k时,p和q一起移动,当p移动到最后一个结点时,q指针所指的就是倒数第k个结点。可以自己画个图出来试试。仅仅遍历一遍就找到了元素k。最容易想到的办法就是,直接遍历一遍,数出有多少个元素,然后再根据元素位置去查找,这样会至多增加一半的时间复杂度。算法效率不高。
typedef in ElemType;
typedef struct LNode{
ElemType data;
struct Lnode *next;
}*LinkList;
int Search_k(LinkList list, int k)
{
//查找链表的倒数第k个结点并输出
LinkList p=list->next,q=list->next;
int count=0;
while(p!=NULL)
{
if(count<k) count++;
else q=q->next;p=p->next; //注意这个地方p=p-next;语句不在判断之中始终执行
}
if(count<k)
return 0;
else {
printf("%d",q->data);
return 1;
}
}
2.将有n(n>1)个整数的数组R中保存的数据循环左移P位。
基本思想是将数组分为两部分,两部分分别逆序,再整体逆序即为所得
void Reverse(int R[],int from,int to){
int i, temp;
for(i=0;i<(to-from+1)/2;i++)
{
temp=R[from+i];
R[from+i]=R[to-i];
R[to-i]=temp;
}
}
void Converse(int R[], int n,int p)
{
Reverse(R,0,p-1);
Reverse(R,p,n-1);
Reverse(R,0,n-1);
}
//算法时间复杂度为O(n),空间复杂度为O(1)
3.求两个有序序列合起来的中位数。
基本思想是根据归并后的结果来判断,设A序列的中位数为a,B序列的中位数为b。如果原先的两个序列中位数相等,那么合并之后的中位数一定是a或者b,容易理解,因为归并后的序列 原先排在ab前面的数归并后一定排在ab的前面,原先排在ab之后的数归并后一定排在ab的后面,ab一定是位于整个序列的中间,那么归并后的中位数一定是a或者b。
如果a<b,那么中位数一定位于序列a到b之间的某个数,因此可以将a之前的数和b之后的数舍弃掉,再从a到b之间去找,同样的可以再从两部分序列中分别找出中位数再比较,重复下去,直到两个序列只含有一个元素为止,则较小的即为所求的中位数。
如果a>b,那么中位数一定位于b到a之间的某个数,因此可以将b之前的数舍弃掉,a之后的数舍弃掉,从a,b之间去找,再剩下的序列中重复上述过程,直到两个序列中只有一个元素,则较小的为中位数。
注意,这里只是假定序列归并了,如果真的归并有序了那么中位数肯定就是数组中间的数,就不用麻烦这么半天了,这样做虽然算法简单,但是效率不高。
int M_Search(int A[],int B[],int n)
{
int s1=0,d1=n-1,m1,s2=0,d2=n-1,m2;
while(s1!=d1 || s2!=d2)
{
m1=(s1+d1)/2;
m2=(s2+d2)/2;
if(A[m1]==B[m2])
return A[m1];
if(A[m1]<B[m2])
{
if((s1+d1)%2==0)
{
s1=m1;
d2=m2;
}
else
{
s1=m1+1;
d2=m2;
}
}
else{
if((s1+d1)%2==0){
d1=m1;
s2=m2;
}
else{
d1=m1+1;
s2=m2;
}
}
}
return A[s1]<B[s2]? A[s1]:[s2];
}
//算法的时间复杂度为O(nlog2n),空间复杂度为O(1)
4.找两个链表的公共链表的起始位置,这两个链表的末端指向了同一个链表。
基本思想是先遍历两个链表求出链表长度,让两个链表末端对齐,对于更长的链表,指针可以先多移动m-n个距离,让两个指针平齐,然后两个指针一起向后遍历,反复比较它们指向的结点的next指针是否相同,若相同则找到。
LinkNode *Find_lst_Common(LinkList str1,LinkList str2)
{
int len1=Length(str1),len2=Length(str2);
LinkNode *p,*q;
for(p=str1;len1>len2;len1--)
p=p->next;
for(q=str2;len1<len2;len2--)
q=q->next;
while(p->next!=NULL && p->next!=q->next)
{
p=p->next;
q=q->next;
}
return p->next;
}