单链表定义和操作

首先是单链表的定义,使用结构体定义两个部分,分别是数据域和指针域。

点击查看代码
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode, *LinkList;

这里可以使用typedef关键字将后续的定义简化。
具体例子如下:

  • 如果这样定义struct LNode{}的话。在定义LNode类型变量的时候我们需要这样写,struct LNode L;
  • 如果是使用typedef可以将struct省略掉。直接这样写:LNode L;

对链表的初始化(带头节点、不带头节点)

点击查看代码
// 无头节点初始化链表 
bool InitListNoHead(LinkList &L){ 
	return (L == NULL);
}

// 有头节点的初始化链表 
bool InitListWithHead(LinkList &L){
	L = (LNode *) malloc(sizeof(LNode));
	if(L == NULL) return 0;
	L->next = NULL;
	return 1;
}

单链表的插入(指定位置插入、节点前后插入)

点击查看代码
// 在链表中指定位置插入值 
bool InsertElemPos(LinkList &L, int pos, int e){
	if(pos < 1) return 0;
	LNode *p = L;
	int j = 0;
	while(p != NULL && j < pos - 1){
		p = p->next;
		j ++;
	}
	if(p == NULL) return 0;
	LNode *t = (LNode*)malloc(sizeof(LNode));
	t->data = e;
	t->next = p->next;
	p->next = t;
	return 1;
}

// 链表中指定节点后面插入(后插) 
bool InsertNextNode(LNode *p, ElemType e){
	if(p == NULL) return 0;
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if(s == NULL) return 0;
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
}

// 链表中指定节点前面插入(前插)
// 注意前插操作要确定是不是第一个节点,是的话要特殊处理
bool InsertPriorNode(LNode *p, ElemType e){
//	cout << (p->data) << endl;
//	p = p->next;
	if(p == NULL) return 0;
	LNode *s = (LNode*)malloc(sizeof(LNode));
	if(s == NULL) return 0;
	s->next = p->next;
	s->data = p->data;
	p->data = e;
	p->next = s;
	return 1;
}

链表的删除操作

点击查看代码
// 删除第pos个节点并传回 
bool DeleteNodePos(LinkList L, int pos, ElemType &e){
	if(pos < 1) return 0;
	LNode *p = L;
	int j = 0;
	while(p != NULL && j < pos - 1){
		p = p->next;
		j ++;
	}
	if(p == NULL || p->next == NULL) return 0;
	e = p->next->data;
	p->next = p->next->next;
	return 1;
}

// 删除指定节点 
// 如果要删除的是最后一个会出现无值可删的bug
bool DeleteNodeVal(LNode *p){
	if(p == NULL) return 0;
	p->data = p->next->data;
	p->next = p->next->next;
	return 1; 
}

获取链表元素以及获取长度

点击查看代码
// 链表中获取第i个节点 
LNode *GetElem(LinkList L, int i){
	if(i < 0) return NULL;
	LNode *p;
	int j = 0;
	p = L;
	while(p != NULL && j < i){
		p = p->next;
		j ++;
	}
	return p;
}

// 链表中获取值为e的节点 
LNode *LocateElem(LinkList L, ElemType e){
	LNode *p = L;
	while(p != NULL && p->data != e){
		p = p->next;
	}
	return p;
}

// 获取链表长度 
int GetLength(LinkList L){
	LNode *p = L;
	int len = 0;
	while(p->next != NULL){
		p = p->next;
		len ++;
	}
	return len;
}

链表头插、尾插实现初始化

点击查看代码
// 尾插节点 
LinkList List_TailInsert(LinkList &L, int n){
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *p = L;
	for(int i = 1;i <= n;i ++){
		cin >> x;
		s = (LNode *)malloc(sizeof(LNode)); 
		s->data = x;
		p->next = s;
		p = s;
	}
	p->next = NULL;
	return L;
}

// 头插节点 (逆置链表操作)
LinkList List_HeadInsert(LinkList &L, int n){
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL; // 没这句话就是无头节点的链表 
	LNode *s, *p = L;
	for(int i = 1;i <= n;i ++){
		cin >> x;
		s = (LNode *)malloc(sizeof(LNode)); 
		s->data = x;
		s->next = p->next;
		p->next = s; 
	}
	return L;
}

output链表
void ListPrint(LNode *L){
LNode *p = L;
p = p->next;
while(p != NULL){
  cout << p->data << ' ';
  p = p->next;
cout << endl;
}

完整代码:

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode, *LinkList;

// 无头节点初始化链表 
bool InitListNoHead(LinkList &L){ 
	return (L == NULL);
}

// 有头节点的初始化链表 
bool InitListWithHead(LinkList &L){
	L = (LNode *) malloc(sizeof(LNode));
	if(L == NULL) return 0;
	L->next = NULL;
	return 1;
}

// 在链表中指定位置插入值 
bool InsertElemPos(LinkList &L, int pos, int e){
	if(pos < 1) return 0;
	LNode *p = L;
	int j = 0;
	while(p != NULL && j < pos - 1){
		p = p->next;
		j ++;
	}
	if(p == NULL) return 0;
	LNode *t = (LNode*)malloc(sizeof(LNode));
	t->data = e;
	t->next = p->next;
	p->next = t;
	return 1;
}

// 链表中指定节点后面插入(后插) 
bool InsertNextNode(LNode *p, ElemType e){
	if(p == NULL) return 0;
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if(s == NULL) return 0;
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
}

// 链表中指定节点前面插入(前插) 
bool InsertPriorNode(LNode *p, ElemType e){
//	cout << (p->data) << endl;
	p = p->next;
	if(p == NULL) return 0;
	LNode *s = (LNode*)malloc(sizeof(LNode));
	if(s == NULL) return 0;
	s->next = p->next;
	s->data = p->data;
	p->data = e;
	p->next = s;
	return 1;
}

// 删除第pos个节点并传回 
bool DeleteNodePos(LinkList L, int pos, ElemType &e){
	if(pos < 1) return 0;
	LNode *p = L;
	int j = 0;
	while(p != NULL && j < pos - 1){
		p = p->next;
		j ++;
	}
	if(p == NULL || p->next == NULL) return 0;
	e = p->next->data;
	p->next = p->next->next;
	return 1;
}

// 删除指定节点 
bool DeleteNodeVal(LNode *p){
	if(p == NULL) return 0;
	p->data = p->next->data;
	p->next = p->next->next;
	return 1; 
}

// 链表中获取第i个节点 
LNode *GetElem(LinkList L, int i){
	if(i < 0) return NULL;
	LNode *p;
	int j = 0;
	p = L;
	while(p != NULL && j < i){
		p = p->next;
		j ++;
	}
	return p;
}

// 链表中获取值为e的节点 
LNode *LocateElem(LinkList L, ElemType e){
	LNode *p = L;
	while(p != NULL && p->data != e){
		p = p->next;
	}
	return p;
}

// 获取链表长度 
int GetLength(LinkList L){
	LNode *p = L;
	int len = 0;
	while(p->next != NULL){
		p = p->next;
		len ++;
	}
	return len;
}

// 尾插节点 
LinkList List_TailInsert(LinkList &L, int n){
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *p = L;
	for(int i = 1;i <= n;i ++){
		cin >> x;
		s = (LNode *)malloc(sizeof(LNode)); 
		s->data = x;
		p->next = s;
		p = s;
	}
	p->next = NULL;
	return L;
}

// 头插节点 (逆置链表操作)
LinkList List_HeadInsert(LinkList &L, int n){
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL; // 没这句话就是无头节点的链表 
	LNode *s, *p = L;
	for(int i = 1;i <= n;i ++){
		cin >> x;
		s = (LNode *)malloc(sizeof(LNode)); 
		s->data = x;
		s->next = p->next;
		p->next = s; 
	}
	return L;
}

// 打印链表 
void ListPrint(LNode *L){
	LNode *p = L;
	p = p->next;
	while(p != NULL){
		cout << p->data << ' ';
		p = p->next;
	}
	cout << endl;
}
int main(){
	LinkList L;
	ElemType val;
	int n; cin >> n;
	List_HeadInsert(L, n);
	ListPrint(L);
	cout << "获取链表长度:\n"; 
	int len = GetLength(L);
	cout << "len:" << len << endl;
	cout << "插入指定位置:\n"; 
	InsertElemPos(L, 3, 3);
	ListPrint(L);
	cout << "插入指定节点的后面:\n"; 
	InsertNextNode(L, 3); 
	ListPrint(L);
	cout << "插入指定节点的前面:\n"; 
	InsertPriorNode(L, 100); 
	ListPrint(L);
	cout << "获取第i个节点:\n"; 
	LNode *T = GetElem(L, 2);
	cout << (T->data) << endl;
	cout << "获取值为e的节点:\n"; 
	T = LocateElem(L, 2);
	cout << (T->data) << endl;	
	cout << "删除第3个节点:\n"; 
	DeleteNodePos(L, 3, val);
	cout << val << endl;
	ListPrint(L);
		
	return 0;
}

posted @ 2024-09-19 20:08  asherof  阅读(109)  评论(0)    收藏  举报