数据结构链表功能的实现

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 999
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;		//Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType;	 //ElemType 为可定义的数据类型,此设为int类型
int index[maxn],t;
typedef struct LNode
{
	ElemType data;	//结点的数据域
	struct LNode *next;		//结点的指针域
}LNode,*LinkList;  //LinkList为指向结构体LNode的指针类型


Status InitList_L(LinkList &L){	//算法2.5 单链表的初始化
	//构造一个空的单链表L
	L=new LNode;	//生成新结点作为头结点,用头指针L指向头结点
	L->next=NULL;    //头结点的指针域置空
	return OK;
}

Status ListInsert_L(LinkList &L,int i,ElemType &e){ //算法2.8 单链表的插入
	//在带头结点的单链表L中第i个位置之前插入元素e
	int j;
	LinkList p,s;
	p=L;j=0;
	while(p && j<i-1){p=p->next;++j;} //寻找第i-1个结点
	if(!p||j>i-1)	return ERROR;	//i大于表长+1或者小于1
	s=new LNode;	//生成新结点s
	s->data=e;		//将结点s的数据域置为e
	s->next=p->next; //将结点s插入L中
	p->next=s;
	return OK;
}//ListInsert_L

void CreateList_F(LinkList &L,int n){ //算法2.10 前插法创建单链表
	//逆位序输入n个元素的值,建立到头结点的单链表L
	LinkList p;
	L=new LNode;
	L->next=NULL; 	//先建立一个带头结点的空链表
	cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
	for(int i=n;i>0;--i){
		p=new LNode; 	//生成新结点
		cin>>p->data;   //输入元素值
		p->next=L->next;L->next=p;  //插入到表头
	}
}//CreateList_F

void CreateList_L(LinkList &L,int n){ //算法2.11 后插法创建单链表
	//正位序输入n个元素的值,建立到头结点的单链表L
	LinkList r,p;
	L=new LNode;
	L->next=NULL; //先建立一个带头结点的空链表
	r=L;          //尾指针r指向头结点
	cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
	for(int i=0;i<n;i++){
		p=new LNode; 	//生成新结点
		cin>>p->data;  	//输入元素值
		p->next=NULL;r->next=p;	 //插入到表尾
		r=p;        	//r指向新的尾结点
	}
}//CreateList_L

Status Getindex(LinkList L, int i){
    //int counts=0;
    memset(index,-1,sizeof(index));
    LinkList P;
    P=L->next;
    t=0;
    int j=0;
    while(P)
    {   //cout<<1<<endl;
        while(P->data!=i&&P->next)
        {P=P->next;j++;/*cout<<1<<endl;*/}
        if(P->data==i) {j++;/*cout<<"j"<<j<<endl;*/;index[t++]=j;}
        if(!P->next) {break;}
        P=P->next;

    }
    return t;
    //return OK;
}//根据输入的值返回对应编号

Status GetMax(LinkList L,ElemType &e){
    LinkList r,p;
    r=L->next;
    int j=0;
    int maxs=0;
    while(r)
    {
        if(r->data>maxs)
        {
           maxs=r->data;
        }
           r=r->next;
           j++;
    }
    e=maxs;
    cout<<"最大值:"<<maxs<<endl;
    int t=Getindex(L,e);
    return t;
    //Getindex(L,e);
}

Status DeleteList(LinkList &L,int i){
    LinkList p,q;
    p=new LNode;
    int j=0;
    p=L;
    while(p->next&&i-1>j){
        p=p->next;
        j++;
    }
    if(!p->next||i-1<j)
        return ERROR;
    q=p->next;
    p->next=q->next;
    delete(q);
    return OK;
}

void ObList(LinkList &L){
    LinkList p,q,r;
    p=L->next;
    q=p->next;
    r=L->next;
    r->next=NULL;
    if(!p||!q)
        return;
    while(q){
        L->next=q;
        p=q->next;
        q->next=r;
        r=q;
        q=p;
    }
}

Status GetElem(LinkList L, int i, ElemType &e){
	LinkList P;
	int j=0;
	P=L;
	while(j<i&&P)
        {P=P->next;j++;}
    if(j>i||!P)
        return ERROR;
    e=P->data;
    return OK;
}//根据输入的编号返回该编号的值

void Deleteitem(LinkList &L,int i){
    LinkList p;
    p=L->next;
    int j=1;
    //cout<<"p:"<<p->data<<endl;
    while(p)
    {   //cout<<1<<endl;
        while(p->data!=i&&p->next)
        {p=p->next;j++;/*cout<<"J1"<<j<<endl;*/}
        if(p->data==i) {p=p->next;DeleteList(L,j);}///要注意删除后,j不再对应是删除后元素在链表中的位置
        if(!p->next) {break;}
    }
}


int main()
{
	int i,n,choose;
	ElemType x;
	LinkList L,p;

	choose=-1;
	while(choose!=0)
	{
		cout<<"******************************************************************************\n";
		cout<<"  1. 建立空链表;                          2. 在表中输入指定个数的数据元素\n";
	    cout<<"  3. 在第i个元素的前插入一个元素;         4. 逐个显示表中数据元素\n";
        cout<<"  5. 查找位序为i的元素,返回其值;         6. 依值查找,返回其位序\n";
	    cout<<"  7. 删除表中第i个元素;                   8. 返回值最大的元素及其在表中位置\n";
	    cout<<"  9. 就地逆置;                            10. 删除表中所有值为item的数据元素\n";
	    cout<<"  0. 退出\n";
		cout<<"*******************************************************************************\n";

		cout<<"请选择:";
		cin>>choose;
		switch(choose)
		{
		case 1:	  //建立一个单链表
			if(InitList_L(L))
				cout<<"成功建立链表!\n\n";
			break;
		case 2:	 //使用后插法创建单链表
			cout<<"请输入一个数,代表元素的个数:";
			cin>>n;
			CreateList_L(L,n);
			cout<<"成功创建链表!\n\n";
			break;
		case 3:  //单链表的插入
			cout<<"请输入两个数,分别代表插入的位置和插入数值(用空格间隔,最后回车):";
			cin>>i>>x;	 //输入i和x,i代表插入的位置,x代表插入的数值
			if(ListInsert_L(L,i,x))
   				cout<<"成功将"<<x<<"插在第"<<i<<"个位置\n\n";
			else
				cout<<"插入失败!\n\n";
			break;
		case 4:	 //单链表的输出
			cout<<"现在链表里的数分别是:";
			p=L->next;
			i=0;
			while(p)
			{
				i++;
				cout<<p->data<<",";
				p=p->next;
			}
			cout<<"共有"<<i<<"个元素。"<<endl<<endl;
			break;
        case 5:
			cout<<"输入你要查找的元素的位序: ";
			cin>>i;//输入i,代表要查找的位序
			//cout<<GetElem(L, i, x)<<endl;
			if(GetElem(L, i, x))
				cout<<"您要查找的元素:"<<x<<endl;
				else cout<<"ERROR"<<endl;
			break;
		case 6:
		    {int k;
            cout<<"输入您要查找位序的元素:"<<endl;
            scanf("%d",&k);
            int n=Getindex(L,k);
             cout<<"一共有"<<n<<"个"<<endl<<"位序分别是:";
                for(int i=0;i<t;i++)
                printf("%d%c",index[i],i==t-1?'\n':' ');}
            //else cout<<"not found"<<endl;
            break;
        case 7:
            cout<<"请输入你要删除的元素的编号:";
            cin>>i;
            if(DeleteList(L,i))
                cout<<"成功删除第"<<i<<"个元素"<<endl;
            else
                cout<<"删除失败"<<endl;
            break;
        case 8:
            {cout<<"返回元素中的最大值及其位置";
            int t=GetMax(L,x);
            /*cout<<"最大值:"<<x;*/
            cout<<"位置:"<<t<<endl;}
            for(int i=0;i<t;i++)
                printf("%d%c",index[i],i==t-1?'\n':' ');
            break;
        case 9:
            cout<<"就地逆置"<<endl;
            ObList(L);
            break;
        case 10:
            cout<<"输入您想要删光的元素:";
            cin>>i;
            Deleteitem(L,i);
                cout<<"已删光所有元素"<<endl;
            //else
              //  cout<<"不存在该元素"<<endl;
            break;
		}
	}
	return 0;
}
就地逆置的另一种写法,思路更清晰(推荐),上面的代码都是自己想的和写的,有一些地方觉得虽然实现了,但是思路不够清晰。
void reverse(LinkList &L)
{
    //单链表为空或只有头结点或只有一个元素,不用进行逆置操作
	if(L==NULL||L->next==NULL||L->next->next==NULL) return;
	
	LNode* p=L->next->next;//令p指向线性表中第2个元素a2
	L->next->next=NULL;//令线性表中第1个元素a1的next为空
	while(p)
	{
                LNode* q=p->next;
		//将p插入到头结点之后
		p->next=L->next;
		L->next=p;

		p=q;//继续访问下一个元素
	}
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链栈是一种基于链表实现的栈数据结构,它使用链表中的节点来存储和操作数据。下面是链栈的基本功能实现方式。 1. 初始化链栈 链栈的初始化操作就是创建一个空链表。我们可以使用一个结构体来表示链表中的节点,节点包含两个部分:数据域和指针域。数据域用来存储元素的值,指针域用来指向下一个节点。 ```c typedef struct Node { int data; // 数据域 struct Node *next; // 指针域 } Node; typedef struct LinkStack { Node *top; // 栈顶指针 int size; // 栈中元素个数 } LinkStack; // 初始化链栈 void initLinkStack(LinkStack *stack) { stack->top = NULL; stack->size = 0; } ``` 2. 判断链栈是否为空 链栈为空的条件是栈顶指针为NULL,即链表中没有节点。 ```c // 判断链栈是否为空 bool isLinkStackEmpty(LinkStack *stack) { return stack->top == NULL; } ``` 3. 入栈操作 链栈的入栈操作就是在链表的头部插入一个新的节点,同时更新栈顶指针和栈中元素个数。 ```c // 入栈操作 void push(LinkStack *stack, int value) { Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = value; newNode->next = stack->top; stack->top = newNode; stack->size++; } ``` 4. 出栈操作 链栈的出栈操作就是删除链表头部的节点,并返回节点中的元素值。如果链表为空,则返回一个特定的错误码或抛出异常。 ```c // 出栈操作 int pop(LinkStack *stack) { if (isLinkStackEmpty(stack)) { // 栈为空 return -1; // 或者通过抛出异常来处理 } Node *p = stack->top; int value = p->data; stack->top = p->next; stack->size--; free(p); return value; } ``` 5. 获取栈顶元素 获取链栈的栈顶元素就是返回链表头部节点的元素值。如果链表为空,则返回一个特定的错误码或抛出异常。 ```c // 获取栈顶元素 int getTop(LinkStack *stack) { if (isLinkStackEmpty(stack)) { // 栈为空 return -1; // 或者通过抛出异常来处理 } return stack->top->data; } ``` 完整代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef struct Node { int data; // 数据域 struct Node *next; // 指针域 } Node; typedef struct LinkStack { Node *top; // 栈顶指针 int size; // 栈中元素个数 } LinkStack; // 初始化链栈 void initLinkStack(LinkStack *stack) { stack->top = NULL; stack->size = 0; } // 判断链栈是否为空 bool isLinkStackEmpty(LinkStack *stack) { return stack->top == NULL; } // 入栈操作 void push(LinkStack *stack, int value) { Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = value; newNode->next = stack->top; stack->top = newNode; stack->size++; } // 出栈操作 int pop(LinkStack *stack) { if (isLinkStackEmpty(stack)) { // 栈为空 return -1; // 或者通过抛出异常来处理 } Node *p = stack->top; int value = p->data; stack->top = p->next; stack->size--; free(p); return value; } // 获取栈顶元素 int getTop(LinkStack *stack) { if (isLinkStackEmpty(stack)) { // 栈为空 return -1; // 或者通过抛出异常来处理 } return stack->top->data; } int main() { LinkStack stack; initLinkStack(&stack); push(&stack, 1); push(&stack, 2); push(&stack, 3); printf("栈顶元素为:%d\n", getTop(&stack)); printf("出栈元素为:%d\n", pop(&stack)); printf("出栈元素为:%d\n", pop(&stack)); printf("出栈元素为:%d\n", pop(&stack)); printf("栈是否为空:%d\n", isLinkStackEmpty(&stack)); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值