不带头结点的单链表和带头结点的单链表
和带有头结点的单链表相比,不带头结点的单链表显得更直观。但不带头结点的单链表在插入和删除第 1 个元素时与插入和删除其它元素时的操作不一样,在创建链表时也不一样,要改变链表头指针的值。而带有头点的单链表无论插入和删除第几个元素,其操作都是统一的。
对插入和删除参数传递存在问题,以及对程序运行后出现的乱码存在问题
不带头结点链表实现
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define Destroy Clear //Destroy和Clear操作是一样的
//和设头结点的单链表在定义存储结构上是相同的
typedef struct Node
{
int data; //数据域
struct Node *next; //指针域
}NODE,*PNODE;
//基本操作
PNODE Create1(); //创建无头结点的单链表,在表头插入数据
PNODE Create2(); //创建无头结点的单链表,在表尾插入数据
void Clear(PNODE pHead);//置空或销毁单链表,
bool Empty(PNODE pHead);//判断单链表是否为空
int Length(PNODE pHead);//返回单链表中元素的个数
bool Get(PNODE pHead,int i,int *e);//将第i个元素的值赋给e
bool Prior(PNODE pHead,int cur_e,int *pre_e);//求cur_e的前驱元素,用pre_e保存
bool Next(PNODE pHead,int cur_e,int *next_e);//求cur_e的后继元素,用next_e保存
bool Insert(PNODE *pHead,int i,int e);//在第i个元素前面插入元素e
bool Delete(PNODE *pHead,int i,int *e);//删除单链表第i个元素,并用e保存
void Traverse(PNODE pHead);//遍历单链表
void Sort(PNODE pHead);//排序
int main()
{
int val;
PNODE pHead=Create1();
printf("初始化链表中的元素为:");
Traverse(pHead);
Get(pHead,3,&val);
printf("第3个元素的值为:%d\n",val);
Insert(&pHead,6,100);
printf("插入第六个元素后:");
Traverse(pHead);
Clear(pHead);
Traverse(pHead);
return 0;
}
PNODE Create1()
{
//在表头插入数据
int i,n;
PNODE pHead=NULL,pNew;
printf("请输入数据元素的个数:");
scanf("%d",&n);
if(n<1)
exit(-1);
pHead=(PNODE)malloc(sizeof(NODE));//生成一个首结点
if(NULL==pHead)
exit(-1);
printf("请输入第1个元素的值:");
scanf("%d",&pHead->data);
pHead->next=NULL;
for(i=0;i<n-1;i++)
{
pNew=(PNODE)malloc(sizeof(NODE));
if(NULL==pNew)
exit(-1);
printf("请输入第%d个元素的值:",i+2);
scanf("%d",&pNew->data);
pNew->next=pHead;
pHead=pNew;
}
return pHead;
}
PNODE Create2()
{
//在表尾插入数据
int i,n;
PNODE pHead=NULL,pNew,pTail;
printf("请输入数据元素的个数:");
scanf("%d",&n);
if(n<1)
exit(-1);
pHead=(PNODE)malloc(sizeof(NODE));//生成一个首结点
if(NULL==pHead)
exit(-1);
printf("请输入第1个元素的值:");
scanf("%d",&pHead->data);
pHead->next=NULL;
pTail=pHead;
for(i=0;i<n-1;i++)
{
pNew=(PNODE)malloc(sizeof(NODE));
if(NULL==pNew)
exit(-1);
printf("请输入第%d个元素的值:",i+2);
scanf("%d",&pNew->data);
pNew->next=pTail->next;
pTail->next=pNew;
pTail=pNew;
}
return pHead;
}
void Clear(PNODE pHead)
{
PNODE p=pHead;
while(p!=NULL)
{
p=pHead->next;
free(pHead);
pHead=p;
}
}
bool Empty(PNODE pHead)
{
if(pHead==NULL)
return true;
else
return false;
}
int Length(PNODE pHead)
{
int count=0;//存放链表元素个数
PNODE p=pHead;
while(p!=NULL)
{
count++;
p=p->next;
}
return count;
}
bool Get(PNODE pHead,int i,int *e)
{
int j=1;
PNODE p=pHead;
while(p!=NULL&&j<i)//找到第i位置
{
j++;
p=p->next;
}
if(j>i||p==NULL)//判断i的值是否合理
return false;
*e=p->data;
return true;
}
bool Prior(PNODE pHead,int cur_e,int *pre_e)
{
PNODE p=pHead,q;
while(p->next!=NULL)
{
q=p->next;
if(cur_e==q->data)
{
*pre_e=p->data;
return true;
}
p=q;
}
return false;
}
bool Next(PNODE pHead,int cur_e,int *next_e)
{
PNODE p=pHead;
while(p->next!=NULL)
{
if(cur_e==p->data)
{
*next_e=p->next->data;
return true;
}
p=p->next;
}
return false;
}
bool Insert(PNODE *pHead,int i,int e)
{
//在不带头结点的单链表第i个位置之前插入元素e
int j=1;
PNODE p=*pHead,pNew;
if(i<1)
return false;
pNew=(PNODE)malloc(sizeof(NODE));
pNew->data=e;
if(i==1)
{
pNew->next=*pHead;
*pHead=pNew;
}
else
{
while(p!=NULL&&j<i-1)
{
p=p->next;
j++;
}
if(p==NULL)
return false;
pNew->next=p->next;
p->next=pNew;
}
}
bool Delete(PNODE *pHead,int i,int *e)
{
int j=1;
PNODE p=*pHead,q;
if(i<1)
return false;
if(i==1)
{
*pHead=p->next;
*e=p->data;
free(p);
}
else
{
while(j<i-1&&p->next!=NULL)
{
j++;
p=p->next;
}
if(p->next==NULL)
return false;
q=p->next;
*e=q->data;
p->next=q->next;
free(q);
}
}
void Traverse(PNODE pHead)
{
PNODE p=pHead;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}