【手记】数据结构-单链表(草记)

作业应用:图书管理系统

结构定义:

struct student{
	ll ISBN;//ISBN号码
	string name;
	ldb price;
	struct student *next;
};

链表的初始化:

student *head = nullptr;
student *p_new = nullptr;

在每次引入新头后,可以添加如下代码,释放节点并防止野指针和空置指针

free(p);
p = nullptr;

计数功能:

//计数功能 
int count(student *head){
	int cnt = 0;
	student *new_head;
	new_head = head;
	while(new_head !=NULL){
		cnt ++;
		new_head = new_head ->next;
	}
	return cnt;
}

查找功能:

按照ISBN或者书名搜索,返回的为节点地址,传递的为头结点和ISBN/书名,这里提供ISBN版本,不同之处仅在于pos的类型

//查找功能
//返回的是一个节点地址 传递的是一个头结点和目标ISBN
student * isbn_search(student *head,ll pos){
	student *new_head;
	new_head = head;
	while(new_head!=NULL){
		if(new_head->ISBN == pos){
			return new_head;
		}
		new_head = new_head ->next;
	}
	return NULL;
}

按照书名搜索:

//按照书名搜索
student * bookname_search(student *head,string pos){
	student *new_head;
	new_head = head;
	while(new_head!=NULL){
		if(new_head->name == pos){
			return new_head;
		}
		new_head = new_head ->next;
	}
	return NULL;
}

删除功能:ISBN和书名都可以

//ISBN删除功能
void ISBNremove(student **head,ll pos){
	student *pb , *pf;
	pf = pb = *head;
	if(*head == NULL){
		
	}
	while(pb ->ISBN != pos && pb->next !=NULL){
		pf = pb;
		pb = pb ->next;
	}
	if(pb->ISBN == pos){
		if(pb == *head){
			*head = pb ->next;
		}
		else{
			pf->next = pb -> next;
		}
	}
	else{
		cout << "节点不存在"<<endl;
	}
}
//name删除功能
void nameremove(student **head,string pos){
	student *pb , *pf;
	pf = pb = *head;
	if(*head == NULL){
		
	}
	while(pb ->name != pos && pb->next !=NULL){
		pf = pb;
		pb = pb ->next;
	}
	if(pb->name == pos){
		if(pb == *head){
			*head = pb ->next;
		}
		else{
			pf->next = pb -> next;
		}
	}
	else{
		cout << "节点不存在"<<endl;
	}
}

库查询(遍历):

//查询功能
void list_print(student *head)
{
	student *now;
	now = head;
	while(now!= nullptr)
	{
		cout << now->ISBN<<" "<< now->name<<" "<<now->price<<endl;;
		now = now->next;
	}
}

一些杂七杂八:

void mainprint(){
	cout << "——————————————————————————首页————————————————————————"<<endl;
	cout <<"———————————————————输入对应数字进入对应操作———————————————————————————"<<endl;
	cout <<"———————————————————首次使用请按9添加一本书籍———————————————————————————————————"<<endl;
	cout <<"0.退出系统"<<endl;
	cout <<"1.进入查询系统"<<endl;
	cout <<"2.进入修改/增删系统"<<endl;
	cout <<"9.系统初始化"<<endl;
	cout <<"请输入:"<<endl;
}

void chaxunprint(){
	cout <<"—————————————————————————查询操作系统———————————————————————————"<<endl;
	cout <<"———————————————————输入对应数字进入对应操作———————————————————————————"<<endl;
	cout <<"1.根据ISBN号查询书籍名称"<<endl;
	cout <<"2.根据书籍名称查询ISBN号"<<endl;
	cout <<"3.输出当前库所有书籍"<<endl;
	cout <<"4.返回上一页"<<endl;
}

void xiugaiprint(){
	cout <<"—————————————————————————修改/增删操作系统———————————————————————————"<<endl;
	cout <<"———————————————————输入对应数字进入对应操作———————————————————————————"<<endl;
	cout <<"1.添加新书籍"<<endl;
	cout <<"2.根据ISBN删除书籍"<<endl;
	cout <<"3.根据书名删除书籍"<<endl;
	cout <<"2.根据ISBN修改书名"<<endl;
	cout <<"3.根据书名修改ISBN"<<endl;
	cout <<"4.返回上一页"<<endl;
}

插入功能:

动态分配新节点并输入新节点数据

student *p_new = new student();
cin >> p_new ->ISBN >> p_new ->name >> p_new ->price;

在有序的链表里插入(在有基础的书库上开始添加),利用ISBN或书名均可

此处提供ISBN版本

void isbn_insert(student ** head,student * pos){
	student *pb ,*pf;
	pb = pf = *head;
	if(*head == nullptr){
		*head = pos;
		pos ->next = nullptr;
		return;
	}
	while((pos ->ISBN >= pb->ISBN)&&(pb->next!= nullptr)){
		pf = pb;
		pb = pb ->next;
	}
	if(pos->ISBN < pb->ISBN){
		if(pb == *head){
			pos->next = *head;
			*head =pos;
		}
		else{
			pf ->next = pos;
			pos->next = pb;
		}
	}
	else{
		pb ->next = pos;
		pos ->next = nullptr;
	}
}

排序功能:(ISBN)

//pf 是前一个节点 pb是后一个节点  temp是冒泡排序的辅助节点
// pf -> next = pb
void isbn_sort(student *head)
{
	student *pb,*pf,temp;
	pf=head;
	if(head== nullptr)
	{
		cout <<"链表为空 无需排序"<<endl;
		return ;
	}
	
	if(head->next == nullptr)
	{
		cout <<"单节点 无需排序" <<endl;
		return ;
	}
	
	while(pf->next != nullptr)
	{
		pb=pf->next;
		while(pb!= nullptr)
		{
			if(pf->ISBN > pb->ISBN)
			{
                //值域交换
				temp=*pb;
				*pb=*pf;
				*pf=temp;
				//指针域交换
				temp.next=pb->next;
				pb->next=pf->next;
				pf->next=temp.next;
			}
			pb=pb->next;
		}
		pf=pf->next;
	}
}

正常插入(适合在创建初期使用):

void add_to_list(student **p_head,student *pos)
{
	student *p_mov = *p_head;
	if(*p_head == nullptr)	
	{
		*p_head = pos;
		pos->next= nullptr;
	}
	else 
	{
        //找到尾结点
		while(p_mov->next!= nullptr)
		{
			p_mov=p_mov->next;
		}
		
		p_mov->next = pos;
		pos->next = nullptr;
	}
}
//数组模拟
void add(int x){
	e[idx] = x;
	ne[idx] = head;
	head = idx;
	idx++;
}

c++数组模拟单链表的实现,与传统的含指针域的单链表的不同之处在于,模拟链表由数组模拟而成,基本功能基本一致,使用动态链表时,每次创新节点的时候,都要new一次是非常慢的,在笔试和算法竞赛中使用后者模拟

本文的数组模拟链表的功能包括:创建(默认),遍历,节点查找,节点删除,插入节点

数组模拟版本:

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int head, e[N], ne[N], idx;

void init() {
	head = -1 ;
	idx = 0;
}

void add_to_head(int x) {
	e[idx] = x;
	ne[idx] = head;
	head = idx;
	idx++;
}

void add(int k, int x) {
	e[idx] = x;
	ne[idx] = ne[k];
	ne[k] = idx;
	idx++;
}

void remove(int k) {
	ne[k] = ne[ne[k]];
}

int main() {
	int m;
	cin >> m;
	init();
	while (m--) {
		int k, x;
		char op;
		cin >> op;
		if (op == 'H') {
			cin >> x;
			add_to_head(x);
		} else if (op == 'D') {
			cin >> k;
			if (!k) head = ne[head];
			remove(k - 1);
		} else {
			cin >> k >> x;
			add(k - 1, x);
		}
	}
	for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
	cout << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值