30/09/2018, 21:17

Lỗi con trỏ danh sách liên kết

Mình bị lỗi này không biết sửa.

SinhVienNode * insertAfter(List & l, SinhVienNode * q, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên

if(p == NULL)	// Nếu cấp phát động thất bại
{
	return NULL;	// Báo thêm thất bại
}

if(q == NULL)	// Nếu danh sách rỗng
{
	addHead(l, p);	// Thêm vào đầu danh sách
}
else
{
	p->pNext = q->pNext;
	q->pNext = p;

	if(l.pTail == q)	// Nếu q là sinh viên cuối danh sách
	{
		l.pTail = p;	// Cập nhập lại p là sinh viên cuối danh sách
	}
}

return p;	// Báo thêm thành công

}

Nguyễn Văn Thường viết 23:28 ngày 30/09/2018

p->pNext = q->pNext;
Xem lại dòng code này xem sao. Có thể bạn tạo liên kết sai sai rồi.

Vu Van Chung viết 23:21 ngày 30/09/2018

thuật toán của bạn thì không thấy sai, rất có thể sai là do mấy cái hàm bạn sử dụng trong thân hàm này như mấy hàm addHead(l,p), bạn có thể đưa cả chương trình lên để xem được không?

Lê Điền Phúc viết 23:29 ngày 30/09/2018

Bạn đã khởi tạo danh sách chưa ?

l.pHead=NULL;
l.pTail=NULL;
```
Nguyễn Đức Anh viết 23:18 ngày 30/09/2018

Đây là toàn bộ code của mình, bạn copy chạy thử kiểm soát lỗi giúp mình nhé :D.
Mình chưa quen với Debug để sửa lỗi lắm

Nguyễn Đức Anh viết 23:25 ngày 30/09/2018

#include “stdafx.h”
#include “stdio.h”
#include “conio.h”
#include “iostream”

#define MSSV 9
#define Ho_Ten 30
#define NamSinh 5

struct SinhVien
{
char strMSSV[MSSV];
char strHoTen[Ho_Ten];
char strNamSinh[NamSinh];
float fDiemTrungBinh;
};

struct SinhVienNode
{
SinhVien info;
SinhVienNode * pNext;
};

struct List
{
SinhVienNode * pHead, * pTail;
};

SinhVienNode * getHead(List & l);

// Hàm khởi tạo danh sách
void init(List & l)
{
l.pHead = l.pTail = NULL;
}

// Hàm thiết lập thông tin cho sinh viên
SinhVien setInfo()
{
SinhVien info;

// Nhập MSSV
fflush(stdin);
printf("Nhap vao MSSV: ");
gets_s(info.strMSSV);

// Nhập họ và tên
fflush(stdin);
printf("Nhap vao ho va ten: ");
gets_s(info.strHoTen);

// Nhập năm sinh
fflush(stdin);
printf("Nhap vao nam sinh: ");
gets_s(info.strNamSinh);

// Nhập điểm trung bình
fflush(stdin);
printf("Nhap vao diem trung binh: ");
scanf_s("%f", & info.fDiemTrungBinh);

return info;

}

// Hàm tạo ra một node sinh viên hoàn chỉnh
SinhVienNode * getNode(SinhVien info)
{
SinhVienNode * p = new SinhVienNode;

if(p == NULL)	// Cấp phát động không thành công
{
	return NULL;
}

p->info = info;
p->pNext = NULL;

return p;

}

// Hàm chỉ sắp xếp sinh viên có sẵn vào đầu danh sách
void addHead(List & l, SinhVienNode * p)
{
if(l.pHead == NULL) // Nếu danh sách rỗng
{
l.pHead = l.pTail = p; // p vừa là đầu, vừa là cuối

	return;
}

p->pNext = l.pHead;
l.pHead = p;

}

// Hàm chỉ sắp xếp sinh viên có sẵn vào cuối danh sách
void addTail(List & l, SinhVienNode * p)
{
if(l.pHead == NULL) // Nếu danh sách rỗng
{
l.pHead = l.pTail = p; // p vừa là đầu, vừa là cuối

	return;
}

l.pTail->pNext = p;
l.pTail = p;

}

// Hàm nhận thông tin sinh viên và sắp xếp vào vị trí đầu danh sách
SinhVienNode * insertHead(List & l, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên

if(p == NULL)	// Nếu cấp phát động thất bại
{
	return NULL;	// Báo thêm thất bại
}

addHead(l, p);	// Thêm vào đầu danh sách

return p;	// Báo thêm thành công

}

// Hàm nhận thông tin sinh viên và sắp xếp vào vị trí cuối danh sách
SinhVienNode * insertTail(List & l, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên

if(p == NULL)	// Nếu cấp phát động thất bại
{
	return NULL;	// Báo thêm thất bại
}

addTail(l, p);	// Thêm vào cuối danh sách

return p;	// Báo thêm thành công

}

// Hàm thêm sinh viên vào giữa danh sách
SinhVienNode * insertAfter(List & l, SinhVienNode * q, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên

if(p == NULL)	// Nếu cấp phát động thất bại
{
	return NULL;	// Báo thêm thất bại
}

if(q == NULL)	// Nếu danh sách rỗng
{
	addHead(l, p);	// Thêm vào đầu danh sách
}
else
{
	p->pNext = q->pNext;
	q->pNext = p;

	if(l.pTail == q)	// Nếu q là sinh viên cuối danh sách
	{
		l.pTail = p;	// Cập nhập lại p là sinh viên cuối danh sách
	}
}

return p;	// Báo thêm thành công

}

// Tạo một danh sách
void createList(List & l)
{
int iSoLuong; // Số lượng sinh viên muốn thêm

do
{
	printf("Nhap vao so luong sinh vien muon then: ");
	scanf_s("%d", & iSoLuong);
}
while(iSoLuong < 1);	// Số lượng sinh viên ít nhất là 1

for(int i = 1; i <= iSoLuong; i++)
{
	printf("\n\n\n");
	printf("Sinh vien thu %d:\n\n", i);

	if( insertTail( l, setInfo() ) == NULL)	// Không đủ bộ nhớ
	{
		printf("Khong du bo nho!");

		break;
	}
}

}

// Hàm tìm sinh viên theo mã số sinh viên
SinhVienNode * searchMSSV(List l, char strMSSV[MSSV])
{
SinhVienNode * p;

// Duyệt từ đầu đến cuối danh sách
for(p = l.pHead; p != NULL; p = p->pNext)
{
	if( strcmp(p->info.strMSSV, strMSSV) == 0 )	// Tìm thấy
	{
		return p;
	}
}

return NULL;	// Không tìm thấy

}

// Hàm tách sinh viên theo mã số sinh viên
SinhVienNode * getMSSV(List l, char strMSSV[MSSV])
{
SinhVienNode * k = l.pHead;

if( strcmp(l.pHead->info.strMSSV, strMSSV) == 0 )	// Tìm thấy là sinh viên đầu danh sách
{
	return getHead(l);
}

// Duyệt từ đầu đến cuối danh sách
for(SinhVienNode * p = l.pHead->pNext; p != NULL; p = p->pNext)
{
	if( strcmp(p->info.strMSSV, strMSSV) == 0 )	// Tìm thấy
	{
		k->pNext = p->pNext;	// Nối lại liên kết chổ bị tháo
		p->pNext = NULL;

		return p;
	}

	k = k->pNext;	// Đảm bảo k đứng trước p để có thể nối lại liên kết
}

return NULL;	// Không tìm thấy

}

// Hàm tìm điểm trung bình cao nhất
float findMax(List l)
{
float fMax;

fMax = l.pHead->info.fDiemTrungBinh;	// Gán mặc định điểm cao nhất của sinh viên đầu

for(SinhVienNode * p = l.pHead; p != NULL; p = p->pNext)
{
	if(fMax < p->info.fDiemTrungBinh)	// Nếu có sinh viên khác cao điểm hơn
	{
		fMax = p->info.fDiemTrungBinh;	// Cập nhập lại điểm cao nhất
	}
}

return fMax;

}

// Xuất ra thông tin một sinh viên
void showSinhVien(SinhVienNode * p)
{
printf("%s - %s - %s - %.1f", p->info.strMSSV, p->info.strHoTen, p->info.strNamSinh, p->info.fDiemTrungBinh);
}

// Xuất ra danh sách thông tin sinh viên
void showList(List l)
{
printf(“Danh sach thong tin sinh vien”);

int i = 1;

// Duyệt từ đầu danh sách đến cuối danh sách
for(SinhVienNode * p = l.pHead;  p != NULL; p = p->pNext)
{
	printf("\n\n\n");
	printf("Sinh vien thu %d\n", i);

	showSinhVien(p);	// Xuất ra thông tin mỗi sinh viên

	i++;
}

}

// Tách sinh viên đầu ra khỏi danh sách
SinhVienNode * getHead(List & l)
{
SinhVienNode * p = NULL;

if(l.pHead != NULL)	// Danh sách không rỗng
{
	p = l.pHead;	// p giữ sinh viên đầu danh sách
	l.pHead = l.pHead->pNext;	// Cập nhập lại đầu danh sách
	p->pNext = NULL;

	if(l.pHead = NULL)	// Nếu danh sách rỗng
	{
		l.pTail = NULL;	// Cập nhập lại cuối danh sách
	}
}

return p;

}

// Tách sinh viên giữa ra khỏi danh sách
SinhVienNode * getAfter(List & l, SinhVienNode * q)
{
SinhVienNode * p = NULL;

if(q != NULL)
{
	p = q->pNext;	// p giữ sinh viên cần tách

	if(p != NULL)	// Nếu q không phải cuối danh sách
	{
		q->pNext = p->pNext;	// Nối lại liên kết chổ sắp tách
		p->pNext = NULL;
	}

	if (p == l.pTail)	// Nếu p là sinh viên cuối danh sách
	{
		l.pTail = q;	// Cập nhập lại cuối danh sách
	}
}
else
{
	p = getHead(l); 
}

return p;

}

// Xóa sinh viên
void delSinhVien(SinhVienNode * p)
{
//SinhVien info;

//info = p->info;	// Giữ thông tin sinh viên sẽ xóa

delete p;	// Xóa sinh viên

//return info;

}

// Xóa danh sách
void delList(List & l)
{
SinhVienNode * p;

while(l.pHead != NULL)	// Lắp đến khi hết danh sách
{
	p = l.pHead;	// p giữ sinh viên đầu cần xóa
	l.pHead = l.pHead->pNext;	// Cập nhập lại đầu danh sách

	delete p;	// Xóa sinh viên
}

l.pTail = NULL;

}

void main()
{
List Lop18TH01;
int iChoise;
int iA;
float fMax;
char strMSSV_Del[MSSV];
char strMSSV_Find[MSSV];

init(Lop18TH01);

SinhVienNode * p = Lop18TH01.pHead;

createList(Lop18TH01);

while(1)
{
	system("cls");

	printf("1 - Xuat danh sach thong tin sinh vien\n");
	printf("2 - Them sinh vien vao dau danh sach\n");
	printf("3 - Them sinh vien vao giua danh sach\n");
	printf("4 - Them sinh vien vao cuoi danh sach\n");
	printf("5 - Xoa sinh vien dau danh sach\n");
	printf("6 - Xoa sinh vien giua danh sach\n");
	printf("7 - Xoa sinh vien theo MSSV\n");
	printf("8 - Tim sinh vien theo MSSV\n");
	printf("9 - Tim sinh vien co diem trung binh cao nhat\n");
	printf("0 - Thoat\n\n");
	printf("Chon: ");
	scanf_s("%d", & iChoise);

	system("cls");

	switch(iChoise)
	{
	case 0:
		return;
	case 1:
		showList(Lop18TH01);
		break;
	case 2:
		insertHead( Lop18TH01, setInfo() );
		break;
	case 3:
		printf("Nhap vao vi tri muon them: ");
		scanf_s("%d", & iA);

		if(iA == 1)
		{
			insertHead( Lop18TH01, setInfo() );
		}
		else
		{
			for(int i = 2; i < iA; i++)
			{
				p = p->pNext;
			}

			insertAfter( Lop18TH01, p, setInfo() );
		}
		break;
	case 4:
		insertTail( Lop18TH01, setInfo() );
		break;
	case 5:
		delSinhVien( getHead(Lop18TH01) );
		printf("Da xoa thanh cong!");
		break;
	case 6:
		break;
	case 7:
		fflush(stdin);
		printf("Nhap vao MSSV can xoa: ");
		gets_s(strMSSV_Del);

		if( getMSSV(Lop18TH01, strMSSV_Del) == NULL )
		{
			printf("Khong tim thay!");
		}
		else
		{
			delSinhVien( getMSSV(Lop18TH01, strMSSV_Del) );

			printf("Da xoa thanh cong!");
		}

		break;
	case 8:
		fflush(stdin);
		printf("Nhap vao MSSV can tim: ");
		gets_s(strMSSV_Find);

		if( searchMSSV(Lop18TH01, strMSSV_Find) == NULL )
		{
			printf("Khong tim thay!");
		}
		else
		{
			showSinhVien( searchMSSV(Lop18TH01, strMSSV_Find) );
		}

		break;
	case 9:
		fMax = findMax(Lop18TH01);

		printf("Sinh vien co diem trung binh cao nhat");

		for(SinhVienNode * p = Lop18TH01.pHead; p != NULL; p = p->pNext)
		{
			if(p->info.fDiemTrungBinh == fMax)
			{
				printf("\n\n\n");
				showSinhVien(p);
			}
		}
		break;
	}

	_getch();
}

}

Bài liên quan
0