单链表的基本运算算法

//----------实现单链表的各种基本运算的算法-----------------
// #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;
    
     

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值