数据结构与算法-4

单链表


定义单链表结点类型

struct LNode{
    
    				 
	ElemType data;			//数据域 
	struct LNode * next		//指针指向下一个节点 
};

增加一个新结点:在内存中申请一个结点所需空间,并用指针p指向这个结点

	struct LNode * p = (struct *) malloc (sizeof(struct LNode));

ps:
struct写的很麻烦,所以可以用typedef,
typedf <数据类型><小名>

typedef int zhengshu;
typedef int * zhengshuzhizhen

zhengshu x = 1//int x = 1 ;
zhengshuzhizhen * p//int * p;

所以增加一个新结点就可以写成

typedef struct LNode LNode;
LNode * p = (LNode *) malloc (seizeof(LNode));

但是这还不够简洁
课本中是这样写的

typedef struct LNode {
    
    				 
	ElemType data;			//数据域 
	struct LNode * next		//指针指向下一个节点 
}LNode, * LinkList;

其实相当于

struct LNode{
    
    				 
	ElemType data;			//数据域 
	struct LNode * next		//指针指向下一个节点 
};

typedef struct LNode LNode;
typedef struct LNode * LinkList;

把struct LNode重命名为LNode
并且用LinkList来表示这是一个指向LNode的指针

要表示一个单链表是,只需要声明一个头指针L,指向单链表第一个结点(找到第一个结点,就相当于找到整个单链表)

LNode *L;//声明一个指向单链表第一个结点的指针

LinkList L//声明一个指向单链表第一个结点的指针

这两种表现方式作用是一样的,但是强调这是一个单链表用LinkList,强调这是一个结点用LNode *。

不带头结点的单链表

#include <iostream>
#include <stdlib.h>
using namespace std;

typedef struct {
    
    				 
	ElemType data;			//数据域 
	struct LNode * next		//指针指向下一个节点 
}LNode, * LinkList;

//初始化一个空的表 
bool InitList(LinkList &L) {
    
    
	L = NULL;			//空表,暂时没有任何结点(防止脏数据) 
	return true;
}

void test(){
    
    
	LinkList L;//声明一个指向单链表的指针
	InitList(L) 
}

//判断单链表是否为空
bool Empty(LinkList L){
    
    
	return (L == NULL);
} 

带头结点的单链表

#include <iostream>
#include <stdlib.h>
using namespace std;

typedef struct {
    
    				 
	ElemType data;			//数据域 
	struct LNode * next		//指针指向下一个节点 
}LNode, * LinkList;

//初始化一个空的表 
bool InitList(LinkList &L) {
    
    
	L = (LNode *) malloc (sizeof(LNode));	//分配一个头结点 
	if (L == NULL)
		return false;
	L -> next= NULL; 
	return true;
}

void test(){
    
    
	LinkList L;//声明一个指向单链表的指针
	
	InitList(L) 
	
}

//判断单链表是否为空
bool Empty(LinkList L){
    
    
	if(L->next == NULL)
		return true;
	else 
		return false;
} 

按位序插入

bool ListInsert(LinkList &L, int i, ElemType e ){
    
    
	if(i<1) 
		return false;
	LNode * p;				//指针p指向当前扫描到的结点 
	int j = 0;				//记录当前p指向的是第几个结点
	P = L;					//L指向头结点,头结点是第0个结点
	
	while (p != NULL && j < i-1 ){
    
    //循环到第i-1个结点 
		p = p->next;
		j++;
	}
	
	if(p == NULL)			//p值不合法 
		return false;
	LNode * s = (LNode *)malloc(sizeof(LNode));
	s->data = e;
	
	s->next = p->next; 
	p->next = s;
	return true;
}

指定结点的后插操作

bool InserNextNode (LNode * p, ElemType e){
    
    
	if (p == NULL)
	return false;
	LNode * s = (LNode *)malloc(sizeof(LNode));
	
	if(s == NULL)		//内存分配失败,计算机被榨干 
		retuen false;	//一般不会出现,只是有可能 

	s->data = e;		//用结点s保存要插入的数据元素e
	s->next = p ->next;
	p -> next = s;
	return true; 
}

指定结点前插(这个牛

bool InserPriorNode(LNode * p, ElemType e){
    
    
	if (p == NULL)
		return false;
	LNode * s = (LNode *)malloc(sizeof(LNode));
	
	if(s == NULL)		
		retuen false;	
	
	s->next = p->next;
	p->next = s;			//新结点s连到p之后 
	s->data = p->data;		//将p中元素复制到s中 
	p->data = e;			//p中元素覆盖为e
	return true; 
} 

按位序删除

bool ListDelete(LinkList &L, int i, ElemType &e ){
    
    
	if(i<1) 
		return false;
	LNode * p;				//指针p指向当前扫描到的结点 
	int j = 0;				//记录当前p指向的是第几个结点
	P = L;					//L指向头结点,头结点是第0个结点
	
	while (p != NULL && j < i-1 ){
    
    //循环到第i-1个结点 
		p = p->next;
		j++;
	}
	
	if(p == NULL)			//p值不合法 
		return false;
	if(p->next == NULL)		//第i-1个结点之后已无其他结点 
	LNode * q = p->next		//令q指向被删除结点 
	e = q->data; 			//用e返回元素的值  & 
	p->next = q->next;		//将*q结点从链中断开 
	free (q);				//释放 
	return true;
}

猜你喜欢

转载自blog.csdn.net/fly_ship/article/details/108934180
今日推荐