关于递归函数,非递归函数中引用传参的问题
首先 我們來看這個函數
typedef int Ele; typedef struct list{Ele data;list *next; }List,*LNode; void dele2(LNode &l,Ele e){if(l==NULL)return;printf("Hello!!\n");printf("to %d\n",l);if(l->data==e){LNode p = l;l = l->next;//***free(p);dele2(l,e);}else dele2(l->next,e);printf("back %d\n",l); }這個函數就是將鏈表中所有為x的節點全部刪除的操作
但是傳參的時候傳入的是一個指向鏈表節點指針的引用類型 也就是說在其中打***的地方?
不會因為沒有把前面的節點鏈接到后面而導致斷鏈 相反
這里的l = l->next 是把當前節點的地址指向了后面
比如對于1 3 1這個鏈表 刪除3操作
第一次走到1 那么遞歸層數加1時 調用dele2(l->next,e); 相當于(*l).next 將該指針所指向的next域的值
取出來并付給更深一層的參數 也就是引用指針&l 那么在此時在刪除3時
會觸發***處的操作 那么這里的操作實質上是 (*l).next = (*(*l).next).next
就相當于直接在1節點的next值修改成了 最后一個節點的地址 也就是相當于整個遞歸過程中對引用指針的操作其實就是對原表
操作
那么引用就是這樣
在遞歸調用的時候 可以直接對原表操作 而且無視可能的斷鏈情況
?
再來看一個函數
void delehead(LNode &p,Ele x){while(p!=NULL){ if(p->data == x){LNode q = p;p = p->next;// pre->next = p;free(q);}else {// pre = p;p = p->next; }} }相同的操作 就是把遞歸改成非遞歸了 相同的是引用 但是這種情況下 就會導致斷鏈
因為當在遞歸中使用引用的過程時 遞歸結束時會把一層層加上的取值操作符再把取值操作符一層層摘掉
而這里卻是讓p不斷指向next 指到最后變成空 因為這里沒有遞歸函數中返回的操作
1 3 1中執行結束的時候 遞歸不斷返回后 原指針指向的是首節點?
而非遞歸中由于沒有返回操作 會不斷地讓頭指針所指向的值一直向后走 最后使頭指針
指到最后的NULL處
所以應另外使用指針非指針引用 這樣不會修改原表的地址 并且附加前后鏈接操作
如果為了防止首元素刪除導致頭指針找不到首節點 應該另外設置頭結點 或者 用計數另外記錄下修改后頭指針
應指向的位置 所以應改為
void delehead(LNode &l,Ele x){// l指向頭結點LNode p = l->next,pre = l;// p指向頭節點的后繼節點 pre指向頭節點 // no head nodewhile(p!=NULL){ if(p->data == x){LNode q = p;p = p->next;pre->next = p;free(q);}else {pre = p;p = p->next; }} }這樣就處理了非遞歸情況下對鏈表中刪除任意位置值為x的操作 如果這里用頭指針的單鏈表
會可能導致由于第一個節點的釋放從而頭指針指向了一個釋放內存的地址
?
總結
以上是生活随笔為你收集整理的关于递归函数,非递归函数中引用传参的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab自定义颜色代码,自定义颜色为
- 下一篇: R 语言PPI网络