Từ 1 tới 4 trên tổng số 4 kết quả

Đề tài: xoá tất cả các phần tử có khoá là x trong DSLK đơn

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

    Mặc định xoá tất cả các phần tử có khoá là x trong DSLK đơn

    mình có bài tập này : xoá toàn bộ các phần tử có khoá là x trong danh sách liên kết đơn ( x tuỳ ý )

    mình đã code thử , mình dùng 1 mảng int *a để đánh dấu xem node đó có trùng với khoá x nhập vào hay không . Nếu trùng thì mình gán nhãn ngay tại node đó bằng 1 Ví dụ : a[p->data]=1. sau đó mình kiểm tra tiếp nếu mà a[p->next->data] == 1 thì mình xoá cái node sau cái node p đó . nhưng có vấn để phát sinh là nếu ta có dãy : 1 2 2 3 thì khi mình chạy vòng for(node *p=phead;p!=NULL;p=p->next) sau khi nó xoá số 2 đầu tiên , thì nó gọi p->next tức là nhảy đến kiểm tra số 3 chứ không kiểm tra tiếp số 2 còn lại . Mong mấy bạn giúp giùm mình nha !!!!!!! tks

    đây là code mình thử test

    Code:
    void xoahet(node *&phead,int x,int n)
    {
    	int *a=(int *)malloc(n*sizeof(int));
    	for(node *p=phead;p!=NULL;p=p->next)
    		if(p->data==x)
    			a[p->data]=1;
    	for(p=phead;p!=NULL;p=p->next)
    		if(a[p->next->data]==1)
    		{
    			node *q=p->next;
    			p->next=q->next;
    			delete q;
    		}
    
    }

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

    1)Ở phần vòng for thứ 2 (vòng để xóa)
    Bạn đang "nhắm mắt để xóa". Đó là lý do vì sao chỉ xóa dc 1 số 2, số 2 còn lại ko xóa dc
    Bạn đứng tại p , xóa tại p->next . Sau khi xóa, bạn nối lại p->next = nút p->next->next. Và nhảy tiếp 1 bước , p=p->next. .
    Và nút bây giờ bạn chỉ có thể xóa dc là p->next->next (trước đó) . Bởi nút p->next (cũ trước đó) đang nằm tại p (hiện tại). Nên nhỡ nó có = khóa x thì ko thể xóa dc. (Vẽ ra giấy sẽ rõ)
    Nói nôm na là . Bạn xóa xong mà chưa kiểm tra lại vị trí chân bạn có = khóa ko.
    Xử lý :
    -Thay vì nhắm mắt xóa, giờ mở mắt xóa: Xóa xong thì khoan nhảy p=p->next. Nếu ko xóa thì mới p=p->next;
    2) Vòng for chỉ nên cho chạy đến p->next!=NULL . Vì nếu chỉ p!=NULL, thì p->next sẽ =NULL nếu p chạy về cuối. Và lúc đó sẽ sinh ra rỗi.
    3) Bạn chưa thực hiện dc công việc XÓA ĐẦU. Nhỡ pHead->data==x thì bị bỏ sót.
    Có 2 cách để giải quyết:
    3.1) Biện luận trường hợp đầu và đưa ra xử lý trước(Khá phiền). Sau đó mới thực hiện xóa thân
    3.2) Chèn vào đầu 1node ảo. Và cứ thế mà xóa, vì chỉ còn trở về trường hợp xóa thân, Xóa xong xuôi thì cắt đầu(node ảo vừa rồi) để trả list về nguyên trạng
    4) Mảng int *a của bạn thật vô dụng khi nó chỉ chứa 1 phần tử(có ý nghĩa nhưng thừa), và phần tử đó là a[x]=1, n-1 phần tử còn lại là "rác" của ram. Và mảng này nó chả có vai trò gì trong code của bạn cả. (Ngẫm lại chút xíu hoặc vẽ ra giấy sẽ rõ)
    Thêm vào đó, nếu trường hợp x > n (Vì mảng a ko có khả năng vươn ra ngoài n) thì sẽ gây lỗi linh tinh gì đấy
    5) Xử lý xong hàm xoa thì phải free(a) (code C) đi kẻo xảy ra hiện tượng "Vứt rác vào ram mà ko ai dọn"

    P/s : Mảng lưu lại địa chỉ các con trỏ là các Node dc đánh dấu để sau đó lần theo mảng này mà xóa thì nghe có lý hơn. Nhưng cũng chả có ý nghĩa gì trong bài xóa này
    Nói chung là chả cần mảng miếc gì cả
    Đã được chỉnh sửa lần cuối bởi clchicken : 30-11-2011 lúc 11:44 PM.
    Um Mani Padme Hum...!!

  3. #3
    Ngày gia nhập
    09 2010
    Bài viết
    17

    Mặc định tác ra 2 hàm sẽ dễ hơn

    theo mình bạn nên tạo 1 hàm xóa riêng để xóa node, hàm này trả về gt là node trước node đã xóa.
    sau đó ba, dùng vòng lặp do while để thực hiện lệnh xóa, nhớ là phải quản lý xem co trỏ p,p->next của bạn ở đâu, vì nếu bạn xóa node p thì p->next cũng ễ mất, nên cần được lưu lại
    Code:
    ode* xoanode(node* &l,node *k)
    {
         node* p,*q;
         p=l;
         while(p!=NULL && p->gt!=k->gt)
         {
                 q=p;
                 p=p->next;      
         }
       
         if(p==l)
         {
                 l=l->next;
                 delete(k);
         }
         else
         if(p!=NULL)
         {
                    q->next=p->next;
                    delete(k);
         }
         return q;
         
    }
    void xoale(node* &l)
    {
         node* p,*q;
         int x;
         p=l;
      do
      {
      x=p->gt;
       if(x%2==1)
          {
                  
                        q = xoanode(l,p);
                      
                        p=q;
          }
          p=p->next;
        
          
       }while(p!=NULL);
        
    }
    đây là hàm xóa các số lẽ trong dslk của mình , bạn tham khảo thử đi

  4. #4
    Ngày gia nhập
    03 2012
    Bài viết
    3

    thuật toán của bạn không xóa đc vị trí đầu tiên
    vd day so :1111112222

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

  1. Cấu trúc dữ liệu Đảo ngược thứ tự các phần tử trong dslk đơn
    Gửi bởi rukawa1184 trong diễn đàn Thắc mắc CTDL & Giải thuật
    Trả lời: 6
    Bài viết cuối: 11-12-2011, 01:00 AM
  2. lỗi sai chèn phần từ vào cuối.... trong dslk
    Gửi bởi nobita_1992 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 8
    Bài viết cuối: 04-11-2011, 04:15 PM
  3. Code cài đặt DSLK đơn vòng và kép vòng trên C++. Thêm 1 phần tử sau 1 phần tử trong DSLK đơn/kép
    Gửi bởi hoanghieu.fit.hcmus trong diễn đàn Thảo luận, góp ý code C/C++ của bạn
    Trả lời: 2
    Bài viết cuối: 09-04-2011, 02:54 PM
  4. Thủ tục loại bỏ các phần tử trùng nhau, giữ lại duy nhất 1 phần tử trong DSLK
    Gửi bởi mrtyoffline trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 02-03-2011, 10:27 PM
  5. Bài toán về chèn 1 phần tử trong dslk
    Gửi bởi coolboy trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 2
    Bài viết cuối: 10-12-2008, 09:44 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