1. 程式人生 > 實用技巧 >有兩個連結串列a和b,設結點中包含學號、姓名。從a連結串列中刪去與b連結串列中有相同學號的那些結點

有兩個連結串列a和b,設結點中包含學號、姓名。從a連結串列中刪去與b連結串列中有相同學號的那些結點

有兩個連結串列a和b,設結點中包含學號、姓名。從a連結串列中刪去與b連結串列中有相同學號的那些結點。

解題思路:

對於b連結串列中的每一個節點,都從a連結串列的表頭開始查詢,如果可以找到,直接刪除,如果找不到,繼續從a連結串列表頭找下一個b的節點。

#include <stdio.h>
typedef struct student
{
	int num;
	double grade;
	struct student *next;
} student;
student *del(student *a, student *b)
{
	student *pre, *current, *head;
	head = a;

	while (b != NULL)
	{
		//重置指標指向a連結串列的頭部
		pre = head;
		current = head->next;
		//a 連結串列的頭等於b
		if (pre->num == b->num)
		{
			pre->next = NULL;
			pre = current;
			current = current->next;
			//更新表頭
			head = pre;
		}
		else
		{
			while (pre->next != NULL)
			{
				if (current->num == b->num)
				{
					//找到就刪除
					pre->next = current->next;
					break;
				}
				else
				{
					//否則繼續遍歷
					pre = pre->next;
					current = current->next;
				}
			}
		}
		b = b->next;
	}
	return head;
}

void printList(student *root)
{
	printf("----\n");
	int i = 0;
	while (root != NULL)
	{
		printf("student %d -> %d -> %.2lf\n", i, root->num, root->grade);
		root = root->next;
		i++;
	}
}

int main()
{
	student a[3] = { { 1, 79 }, { 4, 36 }, { 5, 79 } };
	for (int i = 0; i < 2; i++)
	{
		a[i].next = &a[i + 1];
	}
	a[2].next = NULL;
	printf("連結串列a:\n");
	printList(&a[0]);

	student b[2] = { { 5, 38 }, { 4, 98 } };
	for (int i = 0; i < 1; i++)
	{
		b[i].next = &b[i + 1];
	}
	b[1].next = NULL;
	printf("連結串列b:\n");
	printList(&b[0]);
	student *combine = del(a, b);
	printf("刪除之後:\n");
	while (combine != NULL)
	{
		printf("%d -> %.2lf\n", combine->num, combine->grade);
		combine = combine->next;
	}

	return 0;
}

執行截圖: