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