线性表的链式存储----单链表

        链式存储是最常用的动态存储方法。为了克服顺序表的缺点,可以采用链式方式存储线性表。通常将采用链式存储结构的线性表称为线性链表
        单链表:
        链表是用一组任意的存储单元来存放线性表的结点,这组存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存的任何位置上。因此,链表中结点的逻辑顺序和物理顺序不一定相同。为了正确地表示结点间的逻辑关系,必须在存储线性表的每个数据元素值的同时,存储指示其后继结点的地址(或位置)信息,这两部分信息组成的存储映像称为结点(Node)。如下图所示。
在这里插入图片描述
结点包括两个域:数据域用来存储结点的值,指针域用来存储数据元素的直接后继的地址(或位置)。由于此线性表的每个结点只有一个next域,故称为单链表。
单链表的逻辑状态
                                        单链表的逻辑状态(H为头指针)
单链表的存储结构描述如下:

#include<bits/stdc++.h> 
#define OK 1
#define ERROR 0
using namespace std;
typedef char ElemType;
typedef struct Node{
	ElemType data;
	struct Node* next;
}Node, *LinkList;

LinkList与Node*同为结构指针类型,这两种类型是等价的。通常习惯上用LinkList说明指针变量,强调它是某个单链表的头指针变量。用Node* 来定义指向单链表中结点的指针。
初始化单链表:

void InitList(LinkList *L){
	*L = (LinkList)malloc(sizeof(Node));
	(*L)->next = NULL;
}

建立单链表:
        1.用头插法建立单链表:
在这里插入图片描述


void CreatFromHead(LinkList L){
	Node *s;
	char ch;
	int flag = 1;
	while(flag){/*flag初值为1,当输入"$"时,置flag为0,建表结束*/
		ch = getchar();
		getchar();
		if(ch!='$'){
			s = (Node*)malloc(sizeof(Node));/*建立新结点*/ 
			s->data = ch;
			s->next = L->next;/*将s结点插入表头*/ 
			L->next = s;
		}
		else{
			flag = 0;			
		}
	}
}

        2.用尾插法建立单链表:
在这里插入图片描述

void CreatFromTail(LinkList L){
	Node *r, *s;
	int flag = 1;
	char ch;
	r = L;/*r指针动态指向链表的当前表尾,以便于做尾插入,初值指向头结点*/ 
	while(flag){
		ch = getchar();
		getchar();
		if(ch!='$'){
			s = (Node*)malloc(sizeof(Node));
			s->data = ch;
			r->next = s;
			r = s;
		}
		else{
			flag = 0;
			r->next = NULL;/*最后一个结点的next域置空,表示链表的结束*/ 
		}
	}
}

查找:
        1.按序号查找:

Node* Get(LinkList L, int i){
	int j;
	Node *p;
	if(i <= 0)
	return NULL;
	p = L;
	j = 0;/*从头开始扫描*/ 
	while((p->next!=NULL) && (j < i)){
		p = p->next;
		j++;/*计数器*/ 
	}
	if(i == j)/*找到了第i个结点*/ 
	return p;
	else
	return NULL;
}

        2.按值查找:
                    在单链表L中查找值为key的结点

Node* Locate(LinkList L, ElemType key){
	Node *p;
	p = L->next;/*从表中第一个结点开始*/ 
	while(p != NULL){
		if(p->data != key)
		p = p->next;
		else/*找到key时退出*/ 
		break;
	}
	return p;
}

求单链表的长度:

int ListLength(LinkList L){
	Node *p;
	p = L->next;
	int len = 0;/*存放长度*/ 
	while(p != NULL){
		p = p->next;
		len++;
	}
	return len;
}

单链表插入操作:

int InsList(LinkList L, int i, ElemType e){
	Node *pre, *s;
	int k = 0;
	if(i <= 0)
	return ERROR;
	pre = L;
	while(pre != NULL && k < i-1){
		pre = pre->next;
		k++;
	}
	if(pre == NULL){
		cout<<"插入位置不合理"<<endl;
		return ERROR;
	}
	s = (Node*)malloc(sizeof(Node));/*申请新结点*/ 
	s->data = e;
	s->next = pre->next;/*修改指针,完成插入操作*/ 
	pre->next = s;
	return OK;
}

单链表删除操作:

int DelList(LinkList L, int i, ElemType *e){
	Node *pre, *r;
	int k = 0;
	pre = L;
	while(pre->next != NULL && k < i-1){
		pre = pre->next;
		k++;
	}
	if(pre->next == NULL){
		cout<<"删除结点的位置i不合理"<<endl;
		return ERROR;
	}
	r = pre->next;
	pre->next = r->next;/*修改指针,删除结点*/ 
	*e = r->data;
	free(r);/*释放被删除的结点所占的内存空间*/ 
	return OK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃鱼的ねこ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值