【数据结构】单链表的基本操作

单链表是线性表的链式存储。一般对于每一个节点都会有一个数据域和一个指针域,指针指向下一个节点的地址,所以在逻辑结构上相邻的节点,物理位置可能不是相邻的。
单链表一般会引入一个头结点用于同一处理空表和非空表。对于链表第一个节点的操作无异于其他节点,操作更加方便。
单链表的创建一般有头插法和尾插法。头插法在链表得头结点后插入,这就使得整个链表得顺序与插入时的顺序相反,尾插法在链表中创建了一个尾结点指针,始终指向链表的尾结点,最终链表的顺序与插入元素的顺序一致。

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
using namespace std;

typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode ,*LinkList;					/*LNode只表示线性表的一个节点,LinkList表示的是
									 线性表的指针.可以表示整个线性表。就像数组一样 */

int InitList(LinkList &L);							//创建一个新的线性表	
LinkList ListInsert_Head(LinkList &L,int n);		//线性表的头插法插入元素创建链表 
LinkList ListInsert_Tail(LinkList &L,int n);		//线性表的尾插法插入元素创建链表 
LinkList InsertElem(LinkList &L,int k,ElemType &e);	//插入元素:在第k个位置插入元素e 
LinkList ListDelete(LinkList &L,int k);				//删除元素:删除第k个元素操作 
int TraveList(LinkList &L);							//遍历线性表 
int ElemSearch(LinkList &L,ElemType &e);			//查找元素 
void DestorytList(LinkList &L);						//销毁线性表 
void ClearList(LinkList &L);						//清空线性表 
LinkList UnionList(LinkList &La,LinkList &Lb);		//连接两个线性表 

int main()
{
	LinkList Ha;
	LinkList Hb;
	InitList(Ha);
	InitList(Hb);
	int a=99;
	
	ListInsert_Head(Ha,10);
	TraveList(Ha);
	InsertElem(Ha,9,a);
	TraveList(Ha);
	ListDelete(Ha,6);
	TraveList(Ha);
	int k=ElemSearch(Ha,a);
	cout << k << endl;
	
	//TraveList(Hb);
	ListInsert_Tail(Hb,5);
	TraveList(Hb);
	UnionList(Ha,Hb);
	TraveList(Ha);
	
	ClearList(Ha);
	TraveList(Ha);
	return 0;
}

int InitList(LinkList &L){				//线性表的指针LinkList,&L用来取到地址然后申请内存 
	L=(LinkList)malloc(sizeof(LNode));		//C申请内存 ,L表示头指针 
	//L=new LNode;							//C++申请内存	
	L->next=NULL; 							//L指向了头结点 
	return OK;
}

LinkList ListInsert_Head(LinkList &L,int n){
	LinkList p;								//声明一个节点指针,用于存放数据并做插入操作 
	while(n--){
		p=new LNode;						//创建该节点的指针 
		cin >> p->data;
		p->next=L->next;					//头插法 
		L->next=p;
	}
	return L;
} 

LinkList ListInsert_Tail(LinkList &L,int n){
	LNode *p;								//声明一个结点指针,用于存放数据并做插入操作 
	LinkList r;								//声明一个指针表示尾指针 
	r=L;
	while(n--){
		p=(LinkList)malloc(sizeof(LNode));
		cin >> p->data;
		p->next=NULL;
		r->next=p;							//尾插法,在结尾进行操作 
		r=p; 
	}
	return L;
}

LinkList InsertElem(LinkList &L,int k,ElemType &e){
	LinkList p;
	LinkList q;
	q=L;
	p=(LinkList)malloc(sizeof(LNode));
	p->data=e;								//生成新节点*p,数据域为e 
	int j=0;
	while(q&&j<k-1){						//因为需要放到第k个位置,所以插到k-1的后面即可 
		q=q->next;
		j++;
	} 
	p->next=q->next;
	q->next=p;
	return L;
} 

LinkList ListDelete(LinkList &L,int k){
	int j=0;
	LinkList p;
	LinkList q;
	q=new LNode;
	p=new LNode;
	p=L;
	while(p&&j<k-1){							//指针移到需要删除节点的前一个 
		p=p->next;
		j++;
	}
	//cout << "++++";
	q=p->next;
	p->next=p->next->next;					//修改删除节点的前驱的指针域 
	free(q);								//释放内存 
	return L;
} 

int TraveList(LinkList &L){
	int length=0;
	LinkList p;
	p=L->next;
	while(p!=NULL){
		cout << p->data << " " ;
		p=p->next;
		length++;
	}
	cout << endl;
	cout << "The Length is " << length <<endl;
	return length; 
} 

int ElemSearch(LinkList &L,ElemType &e){
	LinkList p;
	int k=0;
	p=L;
	while(p!=NULL){
		if(p->data==e){
			return k;
		}
		k++;
		p=p->next;
	}
	if(p==NULL)
		return 0;
}

void DestorytList(LinkList &L){
	LinkList p;
	while(L!=NULL){
		p=L;
		L=L->next;
		free(p);
	}
	return ; 
} 
void ClearList(LinkList &L){
	LinkList p;
	while(L->next){
		p=L->next;
		L->next=p->next;
		free(p);
	}
	return ;
}

LinkList UnionList(LinkList &La,LinkList &Lb){
	LinkList p;
	p=La;
	while(p->next){
		p=p->next;
	}
	p->next=Lb->next;			//这里不能直接指向Lb因为Lb也有一个头结点需要直接跳过
	return La;
}

下面是运行结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值