线性表的链表实现

#include<stdio.h>  //printf输出函数和scanf输入函数所在头文件
#include<stdlib.h>  //exit退出函数所在头文件
#include<malloc.h>  //malloc动态内存分配函数、realloc函数所在的头文件
#include<iostream>
using namespace std;

//用#define宏定义来定义符号常量 
//函数结果状态代码 
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
#define ERROR 0
#define INSEASIBLE -1
#define OVERFLOW -2

//用typedef给类型起别名 
typedef int Status;   //Status是函数的类型,其值是函数结果状态代码
typedef int ElemType; //本例中链表各个节点中存储int型数据

//————————————线性表的动态分配存储结构————————————————
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

//构造一个线性链表  前插法 
void CreateList_L(LinkList &L,int n)
{//逆位序输入n个元素的值,建立带头节点的单链线性表L
	L = (LinkList)malloc(sizeof(LNode));//生成新节点做为头节点,用头指针L指向头节点 
	L->next=NULL;//头节点指针域为空
	for(int i=1; i <= n; i++){
		printf("请输入第%d个元素值:\n",i);
		LinkList p = (LinkList)malloc(sizeof(LNode));
		scanf("%d",&p->data);
		p->next=L->next;
		L->next=p;
	} 
}

//构造一个线性表    后插法 
void CreateList_LL(LinkList &L,int n){
	L=(LinkList)malloc(sizeof(LNode));
	L->next=NULL;
	LinkList r=L;
	for(int i =1;i<= n; i++){
		printf("请输入第%d个元素值:\n",i); 
		LinkList p =(LinkList)malloc(sizeof(LNode));
		scanf("%d",&p->data);
		p->next=NULL;
		r->next=p;
		r=p;
	}
} 

//返回当前单连表中元素个数
Status ReturnListNumbers(LinkList L){
	LinkList p = L->next;
	int i=0;
	while(p){
		p=p->next;
		i++;
	} 
	return i;
} 

//复杂度为O(n) 
//在带头节点的单链表L中第i个位置之前插入新的元素e
Status  ListInsert_L(LinkList &L,int i,ElemType e){
	LinkList p=L;
	int j=0;
	while(p&&(j<i-1)){//查找第i-1个节点,p指向该节点 
		p=p->next;
		j++;
	}
	if(!p||j>i-1) return ERROR;
	LinkList s=(LinkList)malloc(sizeof(LNode));
	s->data=e;
	s->next=p->next;
	p->next=s; 
	return OK;
}
//复杂度为O(n) 
//在带头节点的单链表L中删除第i个元素,并用e返回其值
Status ListDelete_L(LinkList &L,int i,ElemType &e) 
{
	LinkList p=L;
	int j=0;
	while(p->next&&(j<i-1)){//找到要删除节点的前驱节点即i-1节点 
		p=p->next;
		j++;
	}
	if(!(p->next)||(j>i-1)) return ERROR;//当i>n或i<1时,删除位置不合理
	LinkList q = p->next;
	p->next=q->next;
	delete q;
	return OK;
}

//在带头节点的单链表L中根据序号i取值 ,并用e返回
Status GetElem_L(LinkList &L,int i,int n,ElemType &e){
	LinkList p=L->next;
	int j=1;
	if(i<1||i>n) return ERROR;
	while(p&&(j<i)){
		j++;
		p=p->next;
	}
	if(!p||j>n) return ERROR;
	e = p->data;
	return OK;
} 

//在带头节点的单链表L中查找值为e的元素
Status LocateElem(LinkList L,int i,ElemType e){
	LinkList p=L->next;
	int j=1;
	while(p&&j<=i){
		if(p->data==e){
			return j;
			break;
		}
		p=p->next;
		j++;
	}
	if(p==NULL||j==i) return ERROR;
} 

////————————合并链表———————————— 
////合并L和L1两表 将所有在L1表中但不再L表中的数据元素添加到L中
//void union_L(LinkList &L,LinkList L1,int n,int n1){
//	int L_len = n;
//	int L1_len = n1;
//	ElemType e;
//	for(int i =1;i <= L1_len; i++){
//		GetElem_L(L1,i,n1,e);
//		if(!LocateElem(L,n,e)){
//			ListInsert_L(L,L_len+2,e);
//			L_len++;
//		}
//	} 
//}

//合并L和L1两表 (不去重),并且将元素按从小到大的顺序排序 
void union_LL(LinkList &L,LinkList L1,int n,int n1){
	int L_len = n;
	int L1_len = n1;
	ElemType e;
	for(int i = 1; i <=L1_len; i++){
		GetElem_L(L1,i,n1,e);
		ListInsert_L(L,L_len+2,e);
		L_len++;
	} 
}

//单链表逆序
void reverseLinkList(LinkList &L){
	LinkList pPre=NULL;//当前节点的上一个节点 
	LinkList pCur=NULL;//指向当前节点的指针 
	LinkList pTmp=NULL;//指向当前节点的下一个节点 
	if(L==NULL||L->next==NULL||L->next->next==NULL){//如果单链表此时只有一个元素,则返回 
		return ;
	} 
	pPre = L->next;
	pCur = L->next->next;
	while(pCur){//遍历链表
		pTmp = pCur->next;
		pCur->next=pPre;
		pPre = pCur;
		pCur = pTmp;
	}
	L->next->next=NULL;
	L->next=pPre;
	 
} 

//给单链表排序 
void Link_sort(LinkList &L)//升序
{
    LinkList q;
    LinkList p=NULL;
    ElemType x;
    for(q=L->next;q->next!=NULL;q=q->next)
    {
        for(p=q->next;p!=NULL;p=p->next)
        {
            if(q->data>=p->data)
            {
                x=q->data;
                q->data=p->data;
                p->data=x;
            }
        }
    }
}

//显示函数,将带头节点的单链线性表L中每个元素逐个显示出来
void ListDisp_L(LinkList L){
	printf("\n当前单链表中的数据是:\n");
	LinkList p = L->next;
	int i=1;
	while(p){
		printf("单链表的第%d个数是%d\n",i,p->data);
		p=p->next;
		i++;
	}
	printf("单链表数据显示完毕!\n");
} 

int main(){
	while(1){
		//——————————初始化单链表—————————— 
		LinkList L,L1;
		int n,n1;
		printf("即将初始化 L 链表,请输入元素个数:\n");
		scanf("%d",&n);
		CreateList_L(L,n);//前插法
		//CreateList_LL(L,n);//后插法 
		ListDisp_L(L);
		
		//—————————插入元素—————————————— 
		ElemType y;
		int m,t;
		printf("请输入要插入多少个数:");
		scanf("%d",&t);
		while(t--){
			printf("请依次输入要插入的 位置 和 要插入的数:");
			scanf("%d%d",&m,&y);
			ListInsert_L(L,m,y);
		}
		printf("\n插入后的状态:");
		ListDisp_L(L);
		
		//——————————删除元素—————————————— 
		ElemType e;
		int x;
		printf("请输入要删除的位置:");
		scanf("%d",&x);
		ListDelete_L(L,x,e);
		printf("\n删除后的状态");
		ListDisp_L(L);
		
		//——————————单链表的取值———————————— 
		ElemType e1;
		int z;
		printf("请输入要取的值的位置:");
		scanf("%d",&z);
		GetElem_L(L,z,n,e1);
		printf("位于第%d位置的元素为:%d \n",z,e1);
		
		//——————————单链表的查找———————————— 
		ElemType e2;
		int n2 = ReturnListNumbers(L);
		printf("请输入要查找的值:");
		scanf("%d",&e2);
		Status p=LocateElem(L,n2,e2);
		if(p)
			printf("元素%d存在单链表中!\n",e2);
		if(p==0) 
			printf("元素%d不在单链表中!\n",e2);
		printf("\n");
		
		//—————————初始化单链表L1———————————— 
		printf("即将初始化 L1 链表,请输入元素个数:\n");
		scanf("%d",&n1);
		CreateList_L(L1,n1);
		ListDisp_L(L1);
		
		//——————————合并两个单链表(去重)—————————— 
//		printf("\n");
//		printf("将L与L1合并后,结果给L后 L 的状态:\n");
//		union_L(L,L1,n,n1);
//		ListDisp_L(L); 
		
		//——————————合并两个单链表(不去重)—————————— 
		printf("将L与L1合并后,结果给L后,L 的状态(不去重):\n");
		union_LL(L,L1,n,n1);
		ListDisp_L(L);
		
		//——————————单链表的逆序———————————— —— 
		printf("\n单链表的逆序:");
		reverseLinkList(L);
		ListDisp_L(L);
		
		//——————————返回当前单链表中元素个数———————— 
		printf("\n当前单链表中元素个数为:%d\n",ReturnListNumbers(L));
		
 		//——————————单链表的排序—————————————— 
 		printf("\n将单链表排序");
		Link_sort(L);
		ListDisp_L(L); 
		printf("\n\n");
	}
	return 0; 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1planet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值