Làm sao để xóa các số nguyên tố trong danh sách liên kết đơn?

Như trên ạ lúc em in ra vẫn danh sách cũ mà các số nguyên tố không bị xóa .Mọi người xem giúp em thuật toán với ạ.Em cảm ơn nhiều <3

#include <iostream>
using namespace std;
struct node {
	int data;
	struct node *pNext;
};
typedef struct node NODE;
struct list {
	NODE *pHead;
	NODE *pTail;
};
typedef struct list LIST;

void KhoiTao(LIST &l) {
	l.pHead = NULL;
	l.pTail = NULL;
}
NODE* KhoiTaoNODE(int x) {
	NODE* p = new NODE;
	if (p == NULL) {
		cout << "Khong du bo nho de cap phat!" << endl;
		return NULL;
	}
	p->data = x;
	p->pNext = NULL;
	return p;
}
void ThemVaoDau(LIST& l, NODE* p) {
	if (l.pHead == NULL) {
		l.pHead = l.pTail = p;
	}
	else {
		p->pNext = l.pHead;
		l.pHead = p;
	}
}
void ThemVaoCuoi(LIST& l, NODE* p) {
	if (l.pTail == NULL) {
		l.pHead = l.pTail = p;
	}
	else {
		l.pTail->pNext = p;
		l.pTail = p;
	}
}
void XuatDanhSach(LIST l) {
	for (NODE *k = l.pHead; k != NULL; k = k->pNext) {
		cout << "\t" << k->data << "  ";
	}
}
void ThemMotNodeVaoTruoc(LIST &l, NODE *p) {
	int x;
	cout << "Them vao truoc so: ";
	cin >> x;
	NODE *q = KhoiTaoNODE(x);
	NODE *g = new NODE;
	for (NODE* k = l.pHead; k != NULL; k = k->pNext) {
		if (q->data == k->data) {
			NODE *h = KhoiTaoNODE(p->data);
			h->pNext = k;
			g->pNext = h;
		}
		g = k;
	}
}
void ThemMotNodeVaoSau(LIST& l, NODE* p) {
	int x;
	cout << "Them vao sau so: ";
	cin >> x;
	NODE *q = KhoiTaoNODE(x);
	for (NODE *k = l.pHead; k != NULL; k = k->pNext) {
			if (q->data == k->data) {
				NODE *h = KhoiTaoNODE(p->data);
				NODE *g = k->pNext;
				h->pNext = g;
				k->pNext = h;
		}
	}
}
int DemSoK(LIST &l) {
	int dem=0;
	int k;
	cout << "Nhap k:";
	cin >> k;
	if (k == 0) {
	    cout << "Vui long nhap k khac 0" << endl;
	}
	for (NODE* p = l.pHead; p != NULL; p = p->pNext) {
		if (k == p->data ) {
			dem++;
		}	
	}
	return dem;
}
void HoanVi(int& x, int& y)
{
	int temp = x;
	x = y;
	y = temp;
}
void SapXep(LIST& l) {
	for (NODE* p = l.pHead; p != l.pTail; p = p->pNext) {
		for (NODE* q = p->pNext; q != NULL; q = q->pNext) {
			if (p->data > q->data) {
				HoanVi(p->data, q->data);
			}
		}
	}
}
void XoaDau(LIST& l) {
	if (l.pHead == NULL) {
		return;
	}
	NODE* p = l.pHead;
	l.pHead = l.pHead->pNext;
	delete p;
}
void XoaCuoi(LIST& l) {
	if (l.pHead == NULL) {
		return;
	}
	for (NODE *k = l.pHead; k != NULL; k = k->pNext) {
		if (k->pNext == l.pTail) {
			delete l.pTail;
			k->pNext = NULL;
			l.pTail = k;
			return;
		}
	}
}
void XoaTatCaSoNguyenTo(LIST& l){
	int flag = 1;
	NODE* truoc = l.pHead;
	for (NODE* k = l.pHead; k != NULL; k = k->pNext){
		if (k->data < 2) {
			flag = 0;
		}
		for (int i = 2; i <= (k->data)/2; i++) {
			if ((k->data) % i == 0) {
				flag = 0;
			}
		}
		if (flag == 1) {
			NODE* sau;
			sau = k->pNext;
			truoc->pNext = sau;
			delete k;
			k = truoc;
		}		
		truoc = k;
	}
}
void Menu(LIST& l) {
	int choice;
	do {
		system("cls");
		cout << "1.Tao danh sach so " << endl;
		cout << "2.Xuat danh sach so" << endl;
		cout << "3.Them mot phan tu vao truoc " << endl;
		cout << "4.Them mot phan tu vao sau " << endl;
		cout << "5.Nhap vao mot so k((k khac 0) va dem xem trong day co bao nhieu so co gia tri = k" << endl;
		cout << "6.Kiem tra trong day co 3 so chan dung canh nhau hay khong (neu co thi in ra)" << endl;
		cout << "7.Sap xep danh sach theo thu tu tang dan" << endl;
		cout << "8.Xoa tat ca cac so nguyen to trong danh sach" << endl;
		cout << "9.Xoa tat ca cac so co gia tri trung nhau trong danh sach, chi giu lai 1 so" << endl;
		cout << "Ban chon: "; cin >> choice;
		switch (choice) {
		case 1: {
			int x;
			cout << "Nhap so:";
			cin >> x;
			NODE* p = KhoiTaoNODE(x);
			ThemVaoCuoi(l, p);
		}
				break;
		case 2: {
			cout << "\tXuat danh sach lien ket" << endl;
			XuatDanhSach(l);
			cout << endl;
			system("pause");
		}
				break;
		case 3: {
			int x;
			cout << "Nhap so can them :";
			cin >> x;
			NODE *p = KhoiTaoNODE(x);
			ThemMotNodeVaoTruoc(l, p);
		}
				break;
		case 4: {
			int x;
			cout << "Nhap so can them: ";
			cin >> x;
			NODE *p = KhoiTaoNODE(x);
			ThemMotNodeVaoSau(l, p);
		}
				break;
		case 5: {
		   int d = DemSoK(l);
		   cout << "Co " << d << " so co gia tri bang k" << endl;
		   system("pause");
		}
				break;
		case 6: {
			XoaCuoi(l);
		}
				break;
		case 7: {
			cout << "Danh sach sau khi sap xep tang dan la: ";
			SapXep(l);
			XuatDanhSach(l);
			cout << endl;
			system("pause");
		}
				break;
		case 8: {
			cout << "Danh sach sau khi xoa cac so nguyen to la: ";
			XoaTatCaSoNguyenTo(l);
			XuatDanhSach(l);
			system("pause");
		}
				break;
		case 9: {
			
		}
				break;
	  }
	} while (choice != 9);

}
int main() {
	LIST l;
	KhoiTao(l);
	Menu(l);
	return 0;
}

Trong hàm XoaTatCaSoNguyenTo(), mình chẳng thấy chỗ nào bạn gán flags = 1 cả, thế mà lại đặt điều kiện if(flags == 1) mới ghê. Ý mình là trong vòng lặp ấy, cái flags = 1 đầu hàm không nghĩa lý gì hết.

4 Likes

1.Tại sao phải cần để trong vòng lặp vậy bạn ?
2.Khi mình để vào trong vòng lặp thì khi nhập xong rồi mình chọn chức năng xóa rồi in ra thì chương trifnh báo lỗi
Exception thrown: read access violation. k was 0xDDDDDDDD.
ở cái dòng
if ((k->data) < 2) đó bạn.Bạn xem giúp mình nha

Trường hợp số đầu tiên (l.pHead) trong danh sách bị xóa thì làm sao?

3 Likes

Em chưa hiểu lắm ý anh nói

Khi phần tử đầu tiên của danh sách là số nguyên tố, nó sẽ bị xóa. Điều gì xảy ra?
Lỗi Exception thrown: read access violation. **variable** was 0xDDDDDDDD. do bạn truy xuất đến 1 biến có giá trị NULL, sau khi gọi delete.

3 Likes

Chỉ có 2 vòng lặp. Chẳng có gì mà loạn.
Đoạn bạn cần sửa chỉ nằm trong:

    		if (flag == 1) {
    			NODE* sau;
    			sau = k->pNext;
    			truoc->pNext = sau;
    			delete k;
    			k = truoc;
    		}

Xét thêm điều kiện là k == l.pHead (phần tử đầu tiên) thì xử lý thế nào? Chỉ 1 dòng!

3 Likes

Em k sửa được anh ơi.Thông não giúp em với ạ hic =(.

Ý bạn SITUVN.gcd là bạn chưa xét phần tử đầu là số nguyên tố.
Giả sử phần tử đầu là số nguyên tố. Lúc này NODE* k = l.pHead; cũng như tương đương với NODE* k = truoc->pHead; nhưng vì là phần tử đầu nên phần tử trước nó phải là NULL tương đương với NODE* truoc = NULL;

sau delete k; thêm k = NULL;delete không gán biến bằng NULL, giá trị của biến sau khi delete vẫn tồn tại.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?