現在一單鏈表,要求用既省時間又省空間的方法找出倒數第m個元素。倒數第m個元素的定義是:當m=0時,返回最后一個元素。寫出設計思路和和C語言作答。給出以下代碼及函數聲明:
兩種思路,前一種是我自己想的,
1,兩個指針,一個先遍歷m下停止,然后在兩個同時遍歷,這時另一個就到是倒數第m個了,稍微一點邏輯思維就可以搞定了,看代碼
element *FindMToLastElement(element *head, int m) {
     element 
*p1, *p2;
     p1 
= head;
     
for(int i = 0; i < m; ++i){
          
if(p1->next)
             p1 
= p1->next;
          
else
             
return NULL;
     }

     p2 
= head;
     
while(p1->next){
         p1 
= p1->next;
         p2 
= p2->next;
     }

     
return p2;
}

2,以前看過的阿諾的解答,整個長度m的循環鏈表遍歷,這樣的話,最后的m個元素都有了。


 2,請說明下面這個程序的輸出,并給予解釋
int  func(int i,int
n)
{
   
return (i<n && printf("%d\n",i)) && !p(i+1
,n)
           
|| printf("%d\n"
,i);
}
3 兩個整型數,不準用if 、switch 、?:等判斷語句求出兩者最大值,說出你的思路,能寫出代碼更好

關于2題,這里有個很好的解釋
已折疊

第3題有很多種解法,我來列舉一下
1,((a+b) + pow((a-b)*(a-b), 0.5))/2,從((a + b) + abs(a - b))/2而來,后者由于abs時加了判斷,所以用pow就顯得聰明了。
2,第二種解法一般用移位:
如果a>b,則a-b的二進制表示中最高位為0,(a-b)>>31 = 0;bigger = m[0];
如果a <b,則a-b的二進制表示中最高位為1,(a-b)>>31 = 1;bigger = m[1];

3,第三種解法主要借助&&和||來判斷,是受到二題的啟發

topic.csdn.net\u\20081030\16\1e4c9e2e-f704-4b24-b53e-169fc8246522.html

如果n為整數,則將它除以2
如果n為奇數,則將它加1或者減1
問對于一個給定的n,怎樣才能用最少的步驟將它變到1
例如
n=61
n-- 60
n/2 30
n/2 15
n++ 16
n/2 8
n/2 4
n/2 2
n/2 1

編程用c/c++
解答:
向4靠攏是有道理的,把數字用二進制表示,通過右移一位、加一、減一,讓他最終變成0(注意,看成變成0的更好理解一些,其實1變成0只是一個“減一”操作,就相差一步),就需要把所有的1消除掉。
怎么去掉1呢,右移不能消除一,只有加減一能夠,所以奇數時要考慮加還是減。
對于...01(2進制)這樣的情形,減一能夠消除1,加一不能,所以要減一;
對于...11,加一能夠至少消除一個1(比如...0111就是消除兩個1),減一只能消除一個1,那么對于...011的情形,應該加一還是減一呢?
答案應該是加一,因為向高位進的1可能會與更高位的1合并為1個連續的1串,使以后加一能夠一下子消除更多的1;
這里有一個例外,就是3(二進制11),因為更高位沒有1了,所以不能加一。