数据结构不带头节点跟带头节点的单链表区别,C语言代码展示

单链表头插法

不带头结点

void FronttList1(List *L) {
	List p;
	ElemType x;
	printf_s("请输入一组数据,以‘0’为结束符\n");
	scanf_s("%d", &x);
	*L = NULL;
	while (x) {
		p = (List)malloc(sizeof(Lnode));
		p->data = x;
		p->next = *L;
		*L = p;
		scanf_s("%d", &x);
	}

}

带头结点

void FrontList2(List *L) {
	List p;
	ElemType x;
	*L = (List)malloc(sizeof(Lnode)); //生成一个空间,给头指针
	(*L)->next = NULL; 
	printf_s("请输入一组数据,以'0'为结束符\n");
	scanf_s("%d", &x);
	while (x) {
		p = (List)malloc(sizeof(Lnode));
		p->data = x;
		p->next = (*L)->next;
		(*L)->next = p;
		scanf_s("%d", &x);
	}
}

区别:此处无明显区别

单链表尾插法:

不带头结点

void RearList1(List *L) {
	List p, r;
	ElemType x;
	*L = r = NULL;
	printf_s("请输入一组数据,以'0'为结束符\n");
	scanf_s("%d", &x);
	while (x) {
		p = (List)malloc(sizeof(Lnode));
		p->data = x;
		if (*L == NULL) {
			*L = p;
		}
		else {
			r->next = p;
		}
		r = p;
		scanf_s("%d", &x);
	}
	if (r)
		r->next = NULL;
}

带头结点

void RearList2(List *L) {
	List r, p;
	ElemType x;
	*L = (List)malloc(sizeof(Lnode));
	(*L)->next = NULL;
	r = *L;
	printf_s("请输入一组数据,以'0'为结束符\n");
	scanf_s("%d", &x);
	while (x) {
		p = (List)malloc(sizeof(Lnode));
		p->data = x;
		p->next = NULL;
		r->next = p;
		r = p;
		scanf_s("%d", &x);
	}


}

 区别:

  • 不带头:结点需要单独考虑首元结点,及最后还要将最后一个元素指针域制空。
  • 带头结点,一气呵成,将首元结点一起考虑进去。

查找第i个元素的值并返回地址

不带头结点

List GetElem1(List L) {
	List p;
	int i;
	int j = 1;
	p = L;
	printf_s("请输入要查找的位置\n");
	scanf_s("%d", &i);

	while (p&&j<i){
		p = p->next;
		j++;
	}
	if (!p|| i < 1) {
		printf_s("该位置不存在\n");
		exit(1);
	}
	printf_s("该值为%d", p->data);
	return L;
}

带头结点

List GetElem2(List L) {
	List p;
	int i;
	int j = 1;
	p = L->next;
	printf_s("请输入要查找的位置\n");
	scanf_s("%d", &i);

	while (p&&j < i) {
		p = p->next;
		j++;
	}
	if (!p || i < 1) {
		printf_s("该位置不存在\n");
		exit(1);
	}
	printf_s("该值为%d", p->data);
	return L;
}

区别:无明显区别

 按值查找

不带头结点

void LocateElem1(List L) {
	ElemType x;
	int i = 1;
	List p;
	p = L;
	printf_s("请输入要查找的值的位置\n");
	scanf_s("%d", &x);
	while(p->data != x&&p) {
		p = p->next;
		i++;
	}
	if (!p) {
		printf_s("无该值\n");
		exit(1);
	}
	else{
		printf_s("该位置%d", i);
	}
}

 带头结点

void LocateElem2(List L) {
	ElemType x;
	int i = 1;
	List p;
	p = L->next;
	printf_s("请输入要查找的值的位置\n");
	scanf_s("%d", &x);
	while (p->data != x && p) {
		p = p->next;
		i++;
	}
	if (!p) {
		printf_s("无该值\n");
		exit(1);
	}
	else {
		printf_s("该位置%d", i);
	}
}

区别:无明显区别

将元素插入指定位置

不带头结点

List ListInsert1(List L) {
	List p,q;
	int i;
	int j = 1;
	q = (List)malloc(sizeof(Lnode));
	q->data = 666;
	p = L;
	printf_s("请输入要插入的位置\n");
	scanf_s("%d", &i);

	while (p&&j < i-1) {
		p = p->next;
		j++;
	}
	if ((!p&&i!=0) || i < 1) {
		printf_s("该位置不存在\n");
		exit(1);
	}
	else {

		if (i == 1) {
			q->next = L;
			L = q;
		}
		else {
			q->next = p->next;
			p->next = q;
		}
	}
	return L;
	
}

带头结点

List ListInsert2(List L) {
	List p,q;
	int i;
	int j = 0;
	q = (List)malloc(sizeof(Lnode));
	q->data = 666;
	p = L;
	printf_s("请输入要插入的位置\n");
	scanf_s("%d", &i);

	while (p&&j < i-1) {
		p = p->next;
		j++;
	}
	if (!p || i < 1) {
		printf_s("该位置不存在\n");
		exit(1);
	}
	q->next = p->next;
	p->next = q;
	return L;
}

 区别

  • 不带头结点:需要单独考虑首元结点,需要单独考虑首元结点,且判断条件还多了是否为空表
  • 带头结点:可一起处理,不用考虑是否非空表

删除指定位置

不带头结点

List  DeleteList1(List L) {
	List p;
	int i;
	int j = 1;
	p = L;
	printf_s("请输入要删除的位置\n");
	scanf_s("%d", &i);

	while (p&&j < i - 1) {
		p = p->next;
		j++;
	}
	if (!p->next || i < 1) {
		printf_s("该位置不存在\n");
		exit(1);
	}
	else {
		if (i == 1) {
			L = p->next ;
		}
		else{
			p->next = p->next->next;
		}
	}
	return L;
}

 带头结点

List  DeleteList2(List L) {
	List p;
	int i;
	int j = 0;
	p = L;
	printf_s("请输入要删除的位置\n");
	scanf_s("%d", &i);
	//判断循环条件
	while (p&&j < i - 1) {
		p = p->next;
		j++;
	}
	//判断表长
	if (!p->next || i < 1) {
		printf_s("该位置不存在\n");
		exit(1);
	}
	p->next = p->next->next;
	return L;
}

区别

  • 不带头结点:需要单独判断首选结点
  • 带头结点:可一起处理

总结:

凡是初始阶段,需要带头结点 “P =L->next” ,与不带头结点做法一样,没有用到头结点的功能;

凡是初始阶段,需要带头结点“P=L”,带头结点做法都比不带头结点方便,不用单独考虑特殊情况

 好处:

便于首元结点的处理

首元结点的地址保存在头结点的指针域中,所以在链表的第一个位置上的操作和其他位置一致,无须特殊处理;

便于空表的统一处理

无论空表是否为空,头指针都是指向头结点的非空指针,因此空表与非空白表的处理也就一样

猜你喜欢

转载自blog.csdn.net/maojiaoliang/article/details/124411985