单链表的实现及其基本操作

关于数据结构中的链表

最近在复习数据结构,之前基本一点都没有看,算是重新开始学习
对于链表的代码实现自己又敲了一遍 。。
记录一下,欢迎大神批评指正

直接上代码


#include<bits/stdc++.h>
#define OK 1
#define ERROR 0
using namespace std;

typedef int Status;
typedef int ElemType;
//链表的定义结构
typedef struct Lnode
{
    ElemType data;//结点的数据域
    struct Lnode *next;//结点的指针域
}Lnode,*LinkList;
//声明结构体后紧跟着定义两个结构体变量
//Lnode 是结点变量
//LinkList 为指向结构体Lnode的指针

//单链表的初始化,用头指针L指向头结点
Status InitList_L(LinkList &L)
{
    L = new Lnode;
    L->next = NULL;
    return OK;
}
//单链表的建立,头插法建立单链表
bool CreateList_H(LinkList &L,int n)
{
    int x;
    L= new Lnode;
    L->next = NULL;//先建立一个带头结点的单链表
    Lnode *p;
    for(int i = n;i>0;i--)
    {
        cin >> x;
        p = new Lnode;
        p->data = x;
        p->next = L->next;
        L->next = p;
    }
    return true;
}
//单链表的建立,尾插法建立单链表
bool CreateList_R(LinkList &L,int n)
{
    int x;
    L = new Lnode;
    L->next = NULL;//建立空的链表
    Lnode *p;
    Lnode *r;//生成一个尾指针
    r = L;//尾指针指向头结点
    for(int i=0;i<n;i++)
    {
        cin >> x;
        p=new Lnode;//申请一个新的结点p
        p->data = x;//将我们要保存的数据置于p的指针域
        p->next = NULL;//再将p的指针域置空,因为要将它置于最后
        r->next = p;//把尾结点的指针域指向p,将p结点接上
        r=p;//尾结点移动到p上
    }
    return true;
    
}
// 判断链表是否为空
Status ListEmpty(LinkList L)
{
    if(L->next) return 0;//非空
    else return 1;
}

//单链表的销毁
Status DestroyList_L(LinkList &L)
{
    Lnode *p;//指向我们当前要销毁的结点
    while(L)//循环条件L!=null
    {
        p=L;
        L= L->next;
        delete p;
    }
    return OK;
}
//单链表的清空
Status ClearList(LinkList &L)
{
    Lnode *p,*q;
    p=L->next;
    while(p)
    {
        q=p->next;
        delete p;
        p=q;
    }
    L->next= NULL;
    return OK;
}
//求单链表的表长
Status ListLength_L(LinkList L)
{
    Lnode *p;
    int i=0;
    p=L->next;
    while(p)
    {
        i++;
        p=p->next;
    }
    return i;
}
//单链表的取值算法-取出单链表中第i个元素的值
Status GetElem_L(LinkList L,int i,ElemType &e)
{
    Lnode *p;
    p=L->next;
    int j=1;
    while (p&&j<i)
    {
        p=p->next;
        j++;
    }
    if(!p||j>i)
    {
        return ERROR;
    }
    e=p->data;
    return e;
}
//单链表的按值查找-根据指定元素获取该元素所在的地址(只返回第一个找到的元素)
Lnode *LocateElem_L(LinkList L,ElemType e)
{
    Lnode *p;
    p=L->next;
    while(p&&p->data!=e)
    {
        p=p->next;
    }
    return p;//返回的是L中值为e的元素的地址
}
//单链表的按值查找-根据指定元素获取该元素所在的位置(只返回第一个找到的元素)
int LocateELem_L(LinkList L,ElemType e)
{
    Lnode *p;
    int j=1;
    p=L->next;//p指向首元结点
    while(p&&p->data!=e)
    {
        p=p->next;
        j++;
    }
    if(p) return j;
    else return 0;
}
//单链表的插入操作-在第i个结点前插入值为e的新结点
//插入在第i个结点前,就作为新的第i个结点
//所以需要找第i-1个结点开始,需要利用它的指针域
Status ListInsert_L(LinkList &L,int i,ElemType e)
{
    Lnode *p,*s;//指针p指向当前扫描到的结点
    int j = 0;// 用j计数当前p指向的是第几个节点
    p=L;//L指向头结点,P=L,且头结点是第0个结点
    while(p&&j<i-1)//寻找到第i-1个结点,p指向i-1结点
    {
        p=p->next;
        j++;
    }
    if(!p||i<1) return ERROR;//i大于表长+1或小于1,非法
    s = new Lnode; 
    s->data = e;//生成新的结点s,将新节点s的数据域置于e
    s->next = p->next;
    p->next = s;
    return OK;
}
//单链表的删除操作-将链表中的第i个元素删除
//同样找到第i-1个结点,将其指针域指向第i+1个结点,释放第i个结点
Status ListDelete_L(LinkList &L,int i/*,ElemType &e*/)
{
    Lnode *p,*q;//指针p指向当前扫描的结点
    int j = 0;// 用j计数当前p指向的是第几个节点
    p=L;//L指向头结点,P=L,且头结点是第0个结点
    while(p&&j<i-1)//寻找第i-1个结点
    {
        p=p->next;
        j++;
    }
    if(!(p->next)||i<1||!p) return ERROR;//删除位置不合理
    q=p->next; // 临时存储的被删除的结点以备释放
    p->next = q->next;//改变被删除节点的前驱节点的指针域
    //e=q->data;//用e存储被删除节点的数据域
    delete q;//释放其空间
    return OK;
}
//打印链表
void ListPrint_L(LinkList L)
{
    cout << "当前链表为" << endl;
    Lnode *p;
    p=L->next;
    while(p)
    {
        cout <<p->data << " "  ;
        p = p->next;
    }
    cout << endl;
}
// *************************************基本功能函数
// 头插法创建一个链表
void Create_H (LinkList &L)
{
    int n; bool flag;
    cout << "请输入你要建立的单链表的长度:";
    cin >> n;
    printf("请输入%d个数:",n);
    flag = CreateList_H(L,n);
    if(flag)
    {
        cout << "创建成功!"<< endl;
        ListPrint_L(L);
    }
    else
    {
        cout << "创建失败"<< endl;
    }
}
// 尾插法创建一个链表
void Create_R (LinkList &L)
{
    int n; bool flag;
    cout << "请输入你要建立的单链表的长度:";
    cin >> n;
    //printf("请输入%d个数:",n);
    cout << "请输入"<< n <<"个数" << endl;
    flag = CreateList_R(L,n);
    if(flag)
    {
        cout << "创建成功!"<< endl;
        ListPrint_L(L);
    }
    else
    {
        cout << "创建失败"<< endl;
    }
}
//插入操作
void Insert (LinkList &L)
{
    int place; 
    ElemType e;
    int k;
    cout << "请输入你要插入的位置及其元素:"<<endl;
    cin >> place >> e ;
    k = ListInsert_L(L,place,e);
    if(k)
    {
        cout << "插入成功!";
        ListPrint_L(L);
    }
}
//删除操作
void Delete (LinkList &L)
{
    int place;
    int k;
    cout << " 请输入你要删除的位置"<< endl;
    cin >> place;
    k = ListDelete_L(L,place);
    if(k)
    {
        cout<< "删除成功!";
        ListPrint_L(L);
    }
}
//查找操作1,根据值返回其位置
void Search1 (LinkList L)
{
    ElemType e;
    int k;
    cout << "请输入你要查找的值:"<< endl;
    cin >> e;
    k = LocateELem_L(L,e);
    if(k)
    {
        cout << "该元素的位置为:"<<k<<endl;
    }
    else
    {
        cout << "未找到该元素!"<<endl;
    }
    
}
//查找操作2,获取某一位置的值
void Search2(LinkList L)
{
    int k;
    ElemType e;
    int place;
    cout << "请输入你要获得的位置"<< endl;
    cin >> place;
    k = GetElem_L(L,place,e);
    if(k)
    {
        cout << "当前位置的值为"<< k<<endl ;
    }
    else
    {
        cout << "输入非法!"<<endl;
    }
    
}
//获取长度
void GetLength(LinkList L)
{
    int k;
    k = ListLength_L(L);
    if(k)
    {
        cout << "当前链表的长度为:"<< k<< endl;
    }
    else
    {
        cout << "当前链表长度为空"<<endl;
    }
    
}
//清空
void Empty (LinkList &L)
{
    int k;
    k = ClearList(L);
    if(k)
    {
        cout << "单链表已清空"<<endl;
    }
}
//判空
void IsEmpty (LinkList L)
{
    int k;
    k = ListEmpty(L);
    if(k)
    {
        cout << "当前单链表为空"<< endl;
    }
}
void menu()
{
    cout <<"1.创建" << endl;
    cout <<"2.打印" << endl;
    cout <<"3.插入" << endl;
    cout <<"4.删除" << endl;
    cout <<"5.查找1" << endl;
    cout <<"6.查找2" << endl;
    cout <<"7.长度" << endl;
    cout <<"8.清空" << endl;
    cout <<"9.判空" << endl;
    cout <<"0.退出" << endl;
}
int main()
{
	LinkList L; int choice;
	InitList_L(L);
	while (1)
	{
		menu();
		printf("请输入菜单序号:\n");
		scanf("%d", &choice);
		if (0 == choice) break;
		switch (choice)
		{
		case 1:Create_R(L); break;//这里调用尾插法进行创建
		case 2:ListPrint_L(L); break;
		case 3:Insert(L); break;
		case 4:Delete(L); break;
		case 5:Search1(L); break;
		case 6:Search2(L); break;
		case 7:GetLength(L); break;
		case 8:Empty(L); break;
        case 9:IsEmpty(L); break;
		default:printf("输入错误!!!\n");
		}
	}
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值