您的位置:首页 > 理论基础 > 数据结构算法

数据结构——带头结点链表和不带头结点链表操作比较

2014-11-26 09:51 423 查看
带头结点的链表和不带头结点的链表主要不同点在插入和删除操作上。同时要注意,带头结点的链表初始化操作时建立头结点。

下面我们来看一下代码中的异同:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>

typedef int elemType;
typedef struct Node{//定义链接节点
elemType element;
Node* next;
}Node;
int insertLast(Node** pNode, elemType ele);
//1、初始化链表,未带头结点
void init(Node** pNode){
*pNode = NULL;
printf("------>链表初始化<------\n");
}

void init_n(Node** pNode){
*pNode = (Node*)malloc(sizeof(Node));//产生头结点,并使pNode头指针指向头结点
if (!(*pNode)){
printf("头结点初始化空间失败\n");
}
printf("------>链表初始化<------\n");
(*pNode)->next = NULL;
}
//1、创建链表
Node* create(Node* pHead){
Node* p1;//代表新节点
Node * p2;//代表尾节点
p1 = p2 = (Node*)malloc(sizeof(Node));//申请节点
if (p1 == NULL || p2 == NULL){
printf("内存空间申请失败\n");
exit(0);
}
memset(p1, 0, sizeof(Node));
printf("输入节点值(非正数结束):");
scanf_s("%d", &p1->element);//输入新节点
p1->next = NULL;
while (p1->element > 0){
if (pHead == NULL){//空节点,接入表头
pHead = p1;
}
else{
p2->next = p1;//非空表,接入尾节点
}
p2 = p1;//重新让p2做尾节点
p1 = (Node*)malloc(sizeof(Node));
if (p1 == NULL || p2 == NULL){
printf("内存分配失败\n");
exit(0);
}
memset(p1, 0, sizeof(Node));
printf("输入节点值(非正数结束):");
scanf_s("%d", &p1->element);
p1->next = NULL;

}

printf("链表创建成功\n");
return pHead;
}

Node* create_n(Node* pHead){
Node* p1;//代表新节点
Node * p2;//代表尾节点
p1 = p2 = (Node*)malloc(sizeof(Node));//申请节点
if (p1 == NULL || p2 == NULL){
printf("内存空间申请失败\n");
exit(0);
}
memset(p1, 0, sizeof(Node));
printf("输入节点值(非正数结束):");
scanf_s("%d", &p1->element);//输入新节点
p1->next = NULL;
while (p1->element > 0){

insertLast(&pHead, p1->element);
memset(p1, 0, sizeof(Node));
printf("输入节点值(非正数结束):");
scanf_s("%d", &p1->element);
p1->next = NULL;

}

printf("链表创建成功\n");
return pHead;
}

//打印链表,不带头结点的情况
void print(Node* pHead){
if (pHead == NULL){
printf("链表为空\n");
}
else{
while (pHead != NULL){

printf("%d,", pHead->element);
pHead = pHead->next;

}
printf("\n");
}
}

//打印链表,带头结点的情况
void print_n(Node* pHead){
pHead = pHead->next;//第一元素结点
if (pHead == NULL){
printf("链表为空\n");
}
else{
while (pHead != NULL){

printf("%d,", pHead->element);
pHead = pHead->next;

}
printf("\n");
}
}

//插入尾节点
int insertLast(Node** pNode, elemType ele){
Node* pInsert;
Node* pHead;
Node* pTmp;

pHead = *pNode;
pTmp = pHead;
pInsert = (Node* )malloc(sizeof(Node));
memset(pInsert, 0, sizeof(Node));
pInsert->element = ele;
while (pHead->next != NULL){
pHead = pHead->next;
}
pHead->next = pInsert;
*pNode = pTmp;
printf("向表尾插入元素:%d\n",ele);
return 1;
}

void main(){
Node* pList=NULL;
Node* list;

init(&pList);
pList = create(pList);
print(pList);

init_n(&list);
pList = create_n(list);
print_n(list);

system("pause");
}


运行结果:



总结:

不带头结点的单链表对于第一个元素结点的操作和其他结点的操作不一致,需要单独处理,容易造成错误。

带头结点的链表与不带头结点的链表,在初始化、删除、遍历输出操作不同(这里我们没有演示删除操作)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息