//----------实现单链表的各种基本运算的算法-----------------
// #include是编译预处理指令 .h是头文件,头文件是包含函数声明和定义的文件;
#include <stdio.h> //包含关于C程序的输入输出的各种信息 stdlib.h
#include <stdlib.h>
#include <malloc.h> //动态存储分配函数头文件
#define MaxSize 10
#define ElemType char //用define 进行宏定义
typedef char CharType; // 用typedef取别名
//定义结点结构 【结构体类型变量的定义】
typedef struct LNode{ //struct LNode是结构体类型名
ElemType data; //数据域
struct LNode *next; //定义一个可以指向LNode结构体类型的指针 ;用于指向下一个结点
//一个指针变量的值就是另外某个变量的地址,所以next可以指向下一个结点
}LinkNode; //LinkNode是通过typedef给 struct LNode 结构体类型取的别名
//初始化单链表
void InitList(LinkNode * &L){ //参数:LinkNode结构体类型的指针
L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点 为其分配内存空间,并返回其首地址
if(L == NULL){
printf("内存空间分配失败!!\n");
exit(0); //exit(0) 表示程序正常退出;exit(1)、exit(-1)表示程序异常退出。
//在整个程序中,只要调用exit,就会结束程序。
}
L->next=NULL; //" -> "是结构体指针使用成员
// 指向结构体的指针称之为结构体指针
}
//头插法建立单链表
void ListInsertF(LinkNode * &L,ElemType a[],int n){ //参数:头指针,插入元素,插入元素个数
LinkNode *s;
InitList(L); //初始化创建头结点
for(int i=0;i<n;i++){
s = (LinkNode *)malloc(sizeof(LinkNode)); //新建结点
if(L == NULL){
printf("内存空间分配失败!!\n");
exit(0);
}
s->data = a[i]; //给s指针指向的结点放入数据
s->next = L->next; //s指向结点中的next指针存储L指向结点的下一个结点地址
L->next = s; // L结点的指针 存储s指针的地址
}
/*--------------------
int *p;
*p 代表这个指针的存储值 ,这个存储值存储其他变量的地址
p 代表这个指针的地址
------------------------*/
}
//尾插法建立单链表
void ListInsertR(LinkNode * &L,ElemType a[],int n){ //参数:头指针,插入元素,插入元素个数
LinkNode *s,*r;
InitList(L); //初始化创建头结点
r = L;
for(int i=0;i<n;i++){
s = (LinkNode *)malloc(sizeof(LinkNode)); //新建结点
s->data = a[i];
r->next = s; //r指针始终指向尾结点,最开始指向头结点,最后置为空
r=s;
}
r->next = NULL;
}
//输出单链表
int DispList(LinkNode *L){
LinkNode *p=L->next; //p指向首结点,而不是头结点 L也是一个结构体类型的指针(头结点)
while(p!=NULL){
printf("%c",p->data);
p=p->next; //p移向下一个结点
}
printf("/n");
}
//输出单链表长度
int ListLength(LinkNode *L){
int i = 0;
LinkNode *p =L;
while(p->next != NULL){
i++;
p=p->next;
}
return (i);
}
//判断单链表是否为空
bool ListEmpty(LinkNode *L){
return(L->next == NULL); //返回值为true该链表为空,否则为非空
}
//输出单链表i个元素
bool GetElem(LinkNode *L,int i,ElemType &e){ //参数:头指针、查找位序、接收查找值的容器
int j=0;
LinkNode *p=L;
if(i<1){
printf("i值错误\n");
return false;
}
while(j<i&& p != NULL){
j++;
p = p->next;
}
if(p == NULL){
printf("不存在第i个结点\n");
return false;
}
e = p->data; //访问p结构体指针中的data成员
return true;
}
//输出元素a的位置
int LocateElem(LinkNode *L,ElemType e){
int i=0;
LinkNode *p=L;
while(p!=NULL && p->data != e){ //找到元素e跳出循环
i++;
p=p->next;
}
if(p == NULL){ //p=null只有两种情况,一种是L表为空,另一种是遍历完整个链表
//没发现元素e
printf("不存在这个结点\n");
return(0);
}
return(i);
}
//在第i个元素位置上插入f元素
bool ListInsert(LinkNode * &L,int i,ElemType e){
int j = 0;
LinkNode * p = L; //p指针用来遍历
LinkNode *s; //s指针用来新建结点
if(i<1){
printf("i值错误\n");
return false;
}
while(j<i-1&&p!=NULL){ //在i位置插入元素,得先找到其前一个结点
j++;
p=p->next;
}
if(p == NULL){ //p=null只有两种情况,一种是L表为空,另一种是遍历完整个链表
//没发现元素e
printf("不存在这个结点\n");
return(false);
}
s = (LinkNode *)malloc(sizeof(LinkNode)); //新建结点
s->data = e; //此时p指针指向第i-1个结点
s->next = p->next; //将s结点插在p结点后面
p->next = s;
printf("插入成功!!\n");
return true;
}
//删除单链表第i个元素
bool ListDelete(LinkNode * &L,int i,ElemType &e){
int j = 0;
LinkNode *p=L,*q;
if(i<1){
printf("i值错误\n");
return false;
}
while(j<i-1 && p!=NULL){
j++;
p=p->next;
}
if(p == NULL){ //p=null只有两种情况,一种是L表为空,另一种是遍历完整个链表
//没发现第i-1个结点
printf("不存在这个结点\n");
return(false);
}
q=p->next; //q指向第i个结点
if(q == NULL){ //p=null只有两种情况,一种是L表为空,另一种是遍历完整个链表
//没发现第i个结点
printf("不存在这个结点\n");
return(false);
}
e = q->data;
p->next=q->next; //第i-1个结点p接到第i+1个结点
free(q);
printf("删除成功!!\n");
return(true);
}
//释放单链表
void DestoryList(LinkNode * &L){
LinkNode *p=L; //从头指针开始释放,p用来释放指针
LinkNode *s=p->next; //s用来保存下一个结点地址
while(s != NULL){
free(p);
p=s;
s=p->next;
}
free(p);
}
//测试文件
#include "LinkList.cpp" //包含单链表的基本运算算法文件
int main(){
//定义头指针;
LinkNode *h;
ElemType e;
printf("单链表的基本运算如下\n");
printf("(1)初始化单链表h\n");
InitList(h);
printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");
ListInsert(h,1,'a');
ListInsert(h,2,'b');
ListInsert(h,3,'c');
ListInsert(h,4,'d');
ListInsert(h,5,'e');
printf("3/输出单链表h");
DispList(h);
printf("4/单链表h长度:%d\n",ListLength(h));
printf("5/单链表h为%s\n",(ListEmpty(h)?"空":"非空"));
GetElem(h,3,e);
printf("6/单链表h的第3个元素:%c\n",e);
printf("7/元素a的位置:%d\n",LocateElem(h,'a'));
printf("8/在第4个元素位置上插入f元素\n");
ListInsert(h,4,'f');
printf("9/输出单链表h:",DispList(h));
printf("10/删除h的第3个元素\n");
ListDelete(h,3,e);
printf("11/输出单链表h:");
DispList(h);
printf("12/释放单链表h\n");
DestoryList(h);
return 1;
}