Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 14 kết quả

Đề tài: Cần giúp về con trỏ

  1. #1
    Ngày gia nhập
    11 2011
    Bài viết
    0

    Mặc định Cần giúp về con trỏ

    Ở đây là xây dựng hàm xóa Node tận cùng bên trái của cây nhị phân
    VD em có cây sau

    1
    /
    2
    /
    3

    Em muốn xóa số 3

    Em có 2 đoạn code sau:

    Đoạn thứ nhất:
    Code:
    void remove() {
    	removeNode(root);
    }
    
    void removeNode(Node *&root) {
    	if (root->left == NULL) {
    		Node* pDel = root;
    		root = root->left;
    		delete pDel;
    	}
    	else {
    		removeNode(root->left);
    	}
    }
    Đoạn thứ 2:
    Code:
    void remove() {
    	Node* pDel = root;
    	while (pDel->left != NULL) {
    		pDel = pDel->left;
    	}
    	removeNode(pDel);
    }
    
    void removeNode(Node *&pNode) {
    	Node* pTemp = pNode;
    	pNode = pNode->left;
    	delete pTem;
    }
    Tại sao sau khi chạy thì đoạn code 1 số 3 thành NULL còn đoạn code 2 thì nó thành 1 giá trị khác chứ không là NULL
    Đã được chỉnh sửa lần cuối bởi newMem : 20-11-2011 lúc 09:37 PM.

  2. #2
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Tại sao khi dùng đoạn code thứ nhất thì sau khi chạy Node cuối cùng bên trái sẽ thành NULL, còn đoạn code thứ 2 thì nó là 1 giá trị khác.
    Thế này nè
    Bạn ko thể nào xóa 1 nút , ngoại trừ khi nó là nút lá.
    Giả sử ta có p , pl=p->left , pr=p->right .
    Giờ bạn muốn xóa pl (tức là nút con trái của p). Trong khi đó , pl đang chứa trong nó thêm 2 cái tay pl->left , pl->right.
    Sau khi xóa pl xong, thì làm sao ta gắn 2 cái tay kia vào cùng 1 chỗ nào được ?

    Nhớ lại hồi học cấp 2 , học môn tin học, tập tẹ với MS-DOS đen đen thân thương đi . Giáo viên bảo : Không thể xóa thư mục trừ khi nó là thư mục rỗng. Mà nếu có muốn xóa thì xóa hẳn luôn những thứ trong nó

    Bây giờ bạn hiểu là cần điều chỉnh lại code thế nào rồi chứ ?
    It's very simple
    Nếu ta có Node* pTemp đang trỏ vào Node cần xóa là 1 lá. Có cách nào xóa Node này mà Node cha của nó sẽ trỏ vào NULL không? (cho đoạn code thứ 2)
    Biết phương pháp "Gậy thằng mù" ko ? .
    Lấy cái khèo, khèo trúng chỗ cần xóa . Ta xóa chỗ đấy, rồi gán lại khèo=NULL
    Cụ thể:
    Ta xóa trái:
    C++ Code:
    1. Ta cần xóa pNode->left chẳng hạn
    2. ptemp=pNode->Left;
    3. Kiểm tra ptemp NULL?? Hoặc ptemp cụt 2 tay thì :
    4.    cout<<"Xin lỗi, anh này đã được chôn cất hoặc vẫn còn tay, ko thể chôn được .
    5.              Bạn cần chặt hết tay rồi mới chôn được ";
    6. Nếu cụt 2 tay thì
    7. {
    8.    
    9.    delete ptemp;
    10.    pNode->Left=NULL ; // Chỗ bạn cần hỏi nè :D
    11.    cout<<"Xin chúc mừng, bạn đã chôn 1 cái xác thành công";
    12. }
    Đã được chỉnh sửa lần cuối bởi clchicken : 20-11-2011 lúc 08:41 PM.

  3. #3
    Ngày gia nhập
    11 2011
    Bài viết
    0

    Trích dẫn Nguyên bản được gửi bởi clchicken Xem bài viết
    Thế này nè
    Bạn ko thể nào xóa 1 nút , ngoại trừ khi nó là nút lá.
    Giả sử ta có p , pl=p->left , pr=p->right .
    Giờ bạn muốn xóa pl (tức là nút con trái của p). Trong khi đó , pl đang chứa trong nó thêm 2 cái tay pl->left , pl->right.
    Sau khi xóa pl xong, thì làm sao ta gắn 2 cái tay kia vào cùng 1 chỗ nào được ?

    Nhớ lại hồi học cấp 2 , học môn tin học, tập tẹ với MS-DOS đen đen thân thương đi . Giáo viên bảo : Không thể xóa thư mục trừ khi nó là thư mục rỗng. Mà nếu có muốn xóa thì xóa hẳn luôn những thứ trong nó

    Bây giờ bạn hiểu là cần điều chỉnh lại code thế nào rồi chứ ?
    It's very simple
    Cái này thì mình biết rồi. ý mình là xóa nút lá khi mà mình có 1 con trỏ trỏ tới nút lá đó. mà nút cha trước khi xóa trỏ tới nó. sau khi xóa trỏ tới NULL

  4. #4
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Trên kia kìa bạn, đọc lại đi. Mình chưa edit bài xong @@ cậu quote nhanh thế

  5. #5
    Ngày gia nhập
    11 2011
    Bài viết
    0

    Vấn đề nó nằm ở chỗ mình chỉ có con trỏ trỏ tới chính Node cần xóa. thì làm sao mà gán con trỏ từ cha nó về nó thành NULL dc hả bạn?
    Đoạn code thứ nhất mình truyền root vào và nó đệ qui tới Node cần xóa và gán nó là NULL. ở đoạn code thứ 2 mình cho chạy tới Node cần xóa rồi gán nó bằng NULL thì lại không được

  6. #6
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Mặc định Cần giúp về con trỏ

    Trích dẫn Nguyên bản được gửi bởi newMem Xem bài viết
    Vấn đề nó nằm ở chỗ mình chỉ có con trỏ trỏ tới chính Node cần xóa. thì làm sao mà gán con trỏ từ cha nó về nó thành NULL dc hả bạn?
    Đoạn code thứ nhất mình truyền root vào và nó đệ qui tới Node cần xóa và gán nó là NULL. ở đoạn code thứ 2 mình cho chạy tới Node cần xóa rồi gán nó bằng NULL thì lại không được
    Thì vấn đề mình cũng đã nói rõ ở bài trên kia rồi đó
    Giải thuật "gậy thằng mù" đấy . Tức là bạn phải làm chủ con trỏ cha của nó, rồi mới xóa dc thằng con. Bạn ko nắm dc thằng cha mà xóa thằng con là ko có đặng .
    Nếu bạn muốn chạy đến thằng con rồi xóa thằng con luôn thì rõ ràng phải tốn thêm 1 công đoạn chạy về lại từ root, rồi đi tìm xem ai là cha của nó ) cực thế ?
    Bạn hỏi thế này chứng tỏ phần DSLK Đơn bạn nắm chưa kĩ. Cũng đừng quá lo lắng
    Soi lại cái giả mã trên kia của mình, ngắn có vài dòng ah, sẽ ngộ ra thôi

    ở đoạn code thứ 2 mình cho chạy tới Node cần xóa
    Bạn chỉ nên chạy đến CHA CỦA NỐT CẦN XÓA
    Đã được chỉnh sửa lần cuối bởi clchicken : 20-11-2011 lúc 08:58 PM.

  7. #7
    Ngày gia nhập
    11 2011
    Bài viết
    0

    Trích dẫn Nguyên bản được gửi bởi clchicken Xem bài viết
    Thì vấn đề mình cũng đã nói rõ ở bài trên kia rồi đó
    Giải thuật "gậy thằng mù" đấy . Tức là bạn phải làm chủ con trỏ cha của nó, rồi mới xóa dc thằng con. Bạn ko nắm dc thằng cha mà xóa thằng con là ko có đặng
    Bạn hỏi thế này chứng tỏ phần DSLK Đơn bạn nắm chưa kĩ. Cũng đừng quá lo lắng
    Soi lại cái giả mã trên kia của mình, ngắn có vài dòng ah, sẽ ngộ ra thôi
    Sorry. Mình hơi chậm tiêu. Nhưng mà phải hỏi cho kĩ "Kẻ thù của tri thức là sự hiểu biết không rõ ràng "
    Thuật giải của bạn thì bạn có cái pNode là cha. khi đó bạn cần xóa pNode->left rồi bạn đưa cái pNode->left = NULL.
    VD mình có hàm find() nó trả về 1 Node*. bây giờ mình cần xóa cái Node nó mới trả về. giả sử là ptemp đi. khi đó mình đâu có cái pNode để có thể gán cái pNode->left = NULL

  8. #8
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Trích dẫn Nguyên bản được gửi bởi newMem Xem bài viết
    Sorry. Mình hơi chậm tiêu. Nhưng mà phải hỏi cho kĩ "Kẻ thù của tri thức là sự hiểu biết không rõ ràng "
    Thuật giải của bạn thì bạn có cái pNode là cha. khi đó bạn cần xóa pNode->left rồi bạn đưa cái pNode->left = NULL.
    VD mình có hàm find() nó trả về 1 Node*. bây giờ mình cần xóa cái Node nó mới trả về. giả sử là ptemp đi. khi đó mình đâu có cái pNode để có thể gán cái pNode->left = NULL
    Heheh, Oke vấn đề rất là đơn giản
    Bạn viết lại hàm find . Ta gọi lại là FatherFind đi
    Thay vì find dừng khi ptemp đạt yêu cầu. Bây giờ FatherFind dừng khi ptemp->left đạt đúng yêu cầu tìm kiếm của mình
    Rồi ta return father
    Bây giờ bạn có trong tay father rồi nhé Thích sai bảo thằng son đi đâu thì cứ sai bảo thoải mái nhé
    ---
    Còn nếu bạn thấy tiếc cái hàm Find thì bạn phải viết thêm 1 cái hàm tìm cha Fatherfind như vậy. Rồi đến lúc bạn muốn xóa thằng con là bạn phải đi tìm cha của nó .
    Nhưng mà vì "tiếc" đấy mà bạn cũng lại tự làm khổ mình như thế đấy
    Đã được chỉnh sửa lần cuối bởi clchicken : 20-11-2011 lúc 09:16 PM.

  9. #9
    Ngày gia nhập
    11 2011
    Bài viết
    0

    Mình cũng đã nghĩ tới cách đó.
    Bây giờ thì bạn hiểu vấn đề mình cần hỏi rồi đó.
    Bạn có thể nào giải thích cho mình tại sao 2 đoạn code đó lại ra 2 KQ khác nhau không?
    1 cái gán NULL được, còn cái kia thì không

  10. #10
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Bạn đã nghĩ tới cách đấy thì bạn bắt tay vào code đi chứ

    2 code trên của bạn toàn code sai cả.
    Và mình chả thấy chỗ nào bạn gán =NULL cả
    Code 1 hàm remove thì mới vào bạn xóa root luôn là sao @@
    Sai thêm 1 chỗ nghiêm trọng là bạn ko kiểm tra nút lá. Bạn chỉ dừng khi p->left ==NULL, vậy nhỡ còn p->right thì sao ? Nó đã cụt hết 2 tay đâu
    Code viết khá tối nghĩa, ko trong sáng gì cả @@
    --
    Những gì mình phân tích đều nằm ở mấy bài viết trên cả rồi. Mình nói rất rõ. Mô tả cũng rất dễ hình dung.
    Bạn chịu khó đọc lại 1 tí, sẽ hiểu ngay thôi. Còn ko hiểu nữa thì mình bó tay, xin nhường quyền trợ giúp cho các tiền bối khác

Các đề tài tương tự

  1. Sự cố Nhờ mod chuyển giúp bài "Sắp xếp số thứ tự ngay trong bảng của 1 database?" từ MySQL sang MSSQL giúp!
    Gửi bởi hu-xeko trong diễn đàn Ý kiến, đề xuất và khiếu nại
    Trả lời: 1
    Bài viết cuối: 12-03-2012, 07:48 PM
  2. Mới nhập môn khó quá , cần trợ giúp [Vấn đề của bạn cần muốn giúp là gì ?]
    Gửi bởi cuingo212 trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 5
    Bài viết cuối: 22-10-2011, 08:43 AM
  3. Chương trình giúp một học sinh cấp 1 học phép nhân, xử lý hàm rand, giúp mình với?
    Gửi bởi chankx trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 2
    Bài viết cuối: 12-05-2009, 08:52 PM
  4. Code giúp add một key vào registry, ai giúp em?
    Gửi bởi olavien trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 5
    Bài viết cuối: 12-12-2007, 08:45 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn