吃完晚饭一直在写,写到现在,弱菜的第一篇博客诞生了!!本文主要介绍线性表中的带头结点的单链表的建立及其操作,如有错误,还请指出!
#include<cstdio>
#include<cstdlib>
typedef char Datatype;
typedef struct node{
Datatype data;
struct node *next;
}ListNode;
typedef ListNode *LinkList;
//****************************建立单链表*************************************
LinkList CreateListR1(){//尾插法建立带头结点的单链表,返回单链表的头指针
char ch;
LinkList head=(ListNode *)malloc(sizeof(ListNode)); //生成头结点
ListNode *s,*r; //工作指针和尾指针
r=head; //尾指针初值也指向头结点
while((ch=getchar())!='\n'){
s=(ListNode *)malloc(sizeof(ListNode)); //生成新结点
s->data=ch; //将读入的数据放入新结点的数据域中
r->next=s; //连接原链表与新结点
r=s; //尾指针移位
}
r->next=NULL; //终端结点的指针域置空,或空表的头结点指针域置空
return head;
}
//**************************单链表的查找运算******************************
ListNode* GetNode(LinkList head,int i){
//在带头结点的单链表head中查找第i个结点(设头结点为第0个结点)
//若找到,则返回该结点的存储位置,否则返回NULL
int j=0;
ListNode *p=head; //从头结点开始扫描
while(p->next&&j<i){ //顺指针向后扫描,直到p->next为NULL或j=i为止
p=p->next;
j++;
}
if(j==i) return p; //找到了第i个结点
else return NULL; //当i<0或0<i<j时,找不到第i个结点
}
ListNode* LocateNode(LinkList head,Datatype key){
//在带头结点的单链表head中查找其值为key的结点
//若找到,则返回首次找到的其值为key的结点的存储位置,否则返回NULL
ListNode *p=head->next; //从开始结点比较。表非空,p初始值指向开始结点
while(p&&p->data!=key){ //直到p为NULL或p->data为key为止
p=p->next; //扫描下一结点
}
return p; //若p=NULL,则查找失败,否则p指向值为key的结点
}
//**************************单链表的插入与删除运算*****************************
void InsertList(LinkList head,Datatype x,int i){
//将值为x的新结点插入到带头结点的单链表head的第i个结点的位置上
ListNode *p;
p=GetNode(head,i-1); //寻找第i-1个结点
if(p==NULL) //i<1或i>n+1时插入位置i有错
printf("Position Error!");
ListNode *s=(ListNode *)malloc(sizeof(ListNode));
s->data=x;
s->next=p->next;
p->next=s;
}
void DeleteList(LinkList head,int i){
//删除带头结点的单链表head上的第i个结点
//注意:设单链表的长度为n,则删去第i个结点仅当1≤i≤n时是合法的
ListNode *p,*r;
p=GetNode(head,i-1); //找到第i-1个结点
if(p==NULL) //i<1或i>n时,删除位置错
printf("Position Error!");
r=p->next; //使r指向被删除的第i个结点
p->next=r->next; //将第i个结点从链上摘下
free(r); //释放结点ai的空间给存储池
}
//*******************************单链表的其他函数*********************************
void PrintList(LinkList head){
//带头结点的单链表head的输出函数
ListNode *p=head->next;
while(p){
printf("%c",p->data);
p=p->next;
if(p!=NULL) printf("->");
}
printf("\n");
}
int ListLength(LinkList head){
//计算带头结点的单链表head的长度
ListNode *p=head->next;
int i=0;
while(p){
i++;
p=p->next;
}
return i;
}
bool ListEmpty(LinkList head){
//判断带头结点的单链表head是否是空链表
//若是空链表则返回true,否则返回false
if(head->next==NULL)
return true;
else return false;
}
void DestroyList(LinkList head){
//销毁单链表head
ListNode *p;
while(head){
p=head->next;
free(head);
head=p;
}
}
//*********************************测试函数****************************************
int main(){
printf("尾插法生成单链表:\n");
LinkList head=CreateListR1();
PrintList(head);
if(ListEmpty(head))
printf("该链表是空链表\n");
else
printf("该链表不是空链表,长度为%d\n",ListLength(head));
printf("该链表第3个位置上的元素是:%c\n",*GetNode(head,3));
printf("该链表在第4个位置上插入元素‘z’后为:\n");
InsertList(head,'z',4);
PrintList(head);
printf("该链表删除第5个位置上元素后为:\n");
DeleteList(head,5);
PrintList(head);
DestroyList(head);
return 0;
}