日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

c语言中删除有序数组中重复元素,去除有序列表中的重复元素

發(fā)布時(shí)間:2023/12/2 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言中删除有序数组中重复元素,去除有序列表中的重复元素 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2014-10-27 09:13:00更新

你仔細(xì)研究一下我寫的 testAsignPoint 和 testAsignPointAgain 函數(shù)就會(huì)明白為什么你的二級(jí)指針無(wú)效了。

還是那句話,你要記住,指針就是一個(gè)變量,存的是32位數(shù)據(jù),記住這個(gè)才能真正的理解指針。

另外 @pezy 說(shuō)有內(nèi)存漏洞,實(shí)際上我的完整代碼是下面的,我大學(xué)是acm出身的,只有初期才使用真正的指針,后期acm中都是使用數(shù)組代表指針的,這才是真正的升華,同樣存的是地址,這時(shí)只不過(guò)地址是數(shù)組的下標(biāo)罷了。

當(dāng)然,下面的代碼我沒有使用數(shù)組代替指針,不然就沒法用指針來(lái)講了。

最后,我加上我的測(cè)試的完整代碼:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

#ifdef __int64

typedef __int64 LL;

#else

typedef long long LL;

#endif

struct ListNode {

int val;

ListNode *next;

ListNode(int x) : val(x), next(NULL) {}

ListNode(int x, ListNode *next) : val(x), next(next) {}

ListNode():next(NULL) {}

} str[100];

ListNode *deleteDuplicates(ListNode *head) {

while(head && head->next) {

if(head->val==head->next->val) {

head->next = head->next->next;

} else {

head = head->next;

}

}

return head;

}

ListNode *oldDeleteDuplicates(ListNode *head) {

ListNode **pcur=&head; //取得 head 變量的

if(head==NULL||head->next==NULL) {//特判是不是沒有元素或者只有一個(gè)元素

return head;

}

/*

這個(gè)時(shí)候 head 是 one 的地址。

pcur 是 head 的地址。

*pcur 就代表 head 了,即 one

(*pcur)->nex 指向 two,所以不結(jié)束循環(huán),且比較相等了

所以你給 *pcur 賦值,也就是給 head 賦值。

此時(shí) *pcur 就指向 two 了。

*/

while((*pcur)->next!=NULL) {

if((*pcur)->val==(*pcur)->next->val) {

*pcur=(*pcur)->next;

// (*pcur)->next =((*pcur)->next->next);

} else {

pcur=&((*pcur)->next);

}

}

return head;

}

void testAsignPoint(ListNode *head) {

printf(" asign begin=%0x\n",head);

head = head->next;

printf(" asign begin=%0x\n",head);

}

void myprintf(ListNode* head) {

while(head != NULL) {

printf("%d ", head->val);

head=head->next;

}

printf("\n");

}

void testAsignPointAgain(unsigned int addr){

printf(" asign begin=%0x\n",addr);

addr = (unsigned int)((ListNode *)addr)->next;//28fef8

printf(" asign begin=%0x\n",addr);

}

void test(ListNode* ptest) {

printf("ptest begin=%0x\n",ptest);//28fef0

testAsignPoint(ptest);

printf("one ptest =%0x\n",ptest);//28fef0

printf("same as before code");

testAsignPointAgain((unsigned int)(ptest));

printf("one ptest =%0x\n",ptest);//28fef0

printf("ptest=%0x\n",ptest);

myprintf(ptest);

oldDeleteDuplicates(ptest);

myprintf(ptest);

deleteDuplicates(ptest);

printf("ptest=%0x\n",ptest);

myprintf(ptest);

}

void testSample(){

ListNode three(1, NULL);

ListNode two(0, &three);

ListNode one(0, &two);

test(&one);

}

int main() {

int n = 10;

for(int i=0; i

str[i].val = i/2;

str[i].next = &str[i+1];

}

str[n].val = n/2;

str[n].next = NULL;

printf("deleteDuplicates begin\n");

myprintf(str);

deleteDuplicates(&str[0]);

myprintf(str);

printf("deleteDuplicates end\n");

printf("\n");

printf("test Asign Point begin\n");

testSample();

printf("test Asign Point begin\n");

return 0;

}

分割線

更新時(shí)間:2014-10-26 15:28

先告訴你我對(duì)指針的定義:指針可以理解為一個(gè)類型,或者一類類型。和int,double,自定義類型等是沒有區(qū)別的。

實(shí)際上最簡(jiǎn)潔的代碼是下面的樣子

ListNode *deleteDuplicates(ListNode *head) {

while(head && head->next) {

if(head->val==head->next->val) {

head->next = head->next->next;

} else {

head = head->next;

}

}

return head;

}

之所以你使用錯(cuò)誤,根本原因是由于你錯(cuò)誤的理解了指針:以指針為參數(shù),只會(huì)修改指針的值,如果對(duì)指針變量修改,原來(lái)那個(gè)指針是不受影響的。

前端時(shí)間剛好我看了一本書《重構(gòu)~改善既有代碼的設(shè)計(jì)》,里面的一個(gè)重構(gòu)目標(biāo)就是對(duì)于串的指針全部改成 final, java 中沒有指針,但是傳的對(duì)象全部是引用,如果添加為 final 就是不能給變量賦值,但是可以修改對(duì)象里面的值。c 語(yǔ)言的 const 也有這個(gè)漏洞,算是hack做法吧,不推薦。

扯遠(yuǎn)了,回頭來(lái)看你的問(wèn)題,不理解的時(shí)候最簡(jiǎn)單的方法就是自己模擬一下。

假設(shè)有鏈表有三個(gè)元素

ListNode three(1, NULL);

ListNode two(0, &three);

ListNode one(0, &two);

結(jié)構(gòu)是這個(gè)樣子:one -> two -> three

為了傳入指針,我們事先一個(gè)函數(shù)吧。

void test(ListNode* pTest){

printf("head=%0x\n",pTest);

deleteDuplicates(pTest);

printf("head=%0x\n",pTest);

}

test(&one);

對(duì)于這個(gè) pTest以參數(shù)形式傳給deleteDuplicates,由于不是引用,所以傳進(jìn)去的是一個(gè)32位數(shù)據(jù),可以稱為地址。

接下來(lái)我們模擬一下你的函數(shù):

ListNode *oldDeleteDuplicates(ListNode *head) {

ListNode **pcur=&head; //取得 head 變量的

if(head==NULL||head->next==NULL) {//特判是不是沒有元素或者只有一個(gè)元素

return head;

}

/*

這個(gè)時(shí)候 head 和 pTest 的值一樣,都是 one 的地址。

pcur 是 head 的地址。

*pcur 就代表 head 了,即 one

(*pcur)->next 指向 two,所以不結(jié)束循環(huán),且比較相等了

所以你給 *pcur 賦值,也就是給 head 賦值。

此時(shí) *pcur 就指向 two 了。

而此時(shí) pTest 還是指向 one 的,而one還是指向two的。

模擬至此,下面再看看為什么是這個(gè)樣子。

*/

while((*pcur)->next!=NULL) {

if((*pcur)->val==(*pcur)->next->val) {

*pcur=(*pcur)->next;

// (*pcur)->next =((*pcur)->next->next);

} else {

pcur=&((*pcur)->next);

}

}

return head;

}

為什么 pTest 沒有改變呢?

我們?cè)贉y(cè)試一下。

void testAsignPoint(ListNode *head) {

printf(" asign begin=%0x\n",head);

head = head->next;

printf(" asign begin=%0x\n",head);

}

void test(ListNode* ptest) {

printf("test begin=%0x\n",ptest);

testAsignPoint(ptest);

printf("test end =%0x\n",ptest);

}

test(&one);

輸出時(shí)下面的數(shù)據(jù)

test begin=28fef0

asign begin=28fef0

asign begin=28fef8

test end =28fef0

ptest 的地址是不會(huì)改變的,因?yàn)槟銈鞯氖?ptest 的值,而不是 ptest 的地址。

分割線

原始回答:

根據(jù)你的算法:*pcur=(*pcur)->next;得到一個(gè)結(jié)論: 當(dāng)重復(fù)時(shí),你刪除的是前一個(gè)

但是如果頭部重復(fù)的時(shí)候,你只是改變一下指針,這樣的算法肯定不能解決頭部問(wèn)題的。

你需要改變算法為:當(dāng)重復(fù)的時(shí)候,刪除后一個(gè)。

即使后面的你一定要使用你的那個(gè)算法,那頭部就只有特判然后使用 重復(fù)時(shí)刪除后面的 算法

刪除后一個(gè)的算法如下:

ListNode *deleteDuplicates(ListNode *head) {

ListNode **pcur=&head;

if(head==NULL||head->next==NULL) {

return head;

}

while((*pcur)->next!=NULL) {

if((*pcur)->val==(*pcur)->next->val) {

// *pcur=(*pcur)->next;

(*pcur)->next =((*pcur)->next->next);

} else {

pcur=&((*pcur)->next);

}

}

return head;

}

總結(jié)

以上是生活随笔為你收集整理的c语言中删除有序数组中重复元素,去除有序列表中的重复元素的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。