204LinkList

C++实现链表基本操作

注意:要严格按照后缀名新建文件。

如果按.h创建文件,后来简单重命名为.cpp文件,编译会出错。

顺序表的实现 包含6个文件:

    c1.h 是预处理指令;

    elemtype.h  定义Elemtype数据类型;

    c2-2.h 是LinkList的数据结构;

    bo2-2.cpp 是SqList的基本操作函数(basic operations 缩写为 bo);

    function.h 定义bo2-2.cpp中,链表遍历函数ListTraverse所需要的访问函数;

    main.cpp 是实现、测试函数。

//c1.h
#include<iostream>
#include<process.h>
#include<malloc.h>

#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef int Status;
//elemtype.h
typedef int ElemType;
//c2-2.h
#ifndef C2_2_H
#define C2_2_H

#include"elemtype.h"
struct LNode
{
	ElemType data;
	LNode *next;
};

typedef LNode* LinkList;

void InitList(LinkList &L);
void ListTraverse(LinkList L, void(*vi)(ElemType));
Status ListInsert(LinkList &L, int index, ElemType e);
Status ListDelete(LinkList &L, int index, ElemType &e);
bool ListEmpty(LinkList L);
int ListLength(LinkList L);
Status GetElem(LinkList L, int index, ElemType &e);
int LocateElem(LinkList L, ElemType e);
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);
void ClearList(LinkList &L);
void DestroyList(LinkList &L);

#endif
//bo2-2.cpp
#include"c1.h"
#include"c2-2.h"
using namespace std;

void InitList(LinkList &L)
{
	L = (LinkList)malloc(sizeof(LNode));
	if (!L)
		exit(OVERFLOW);
	L->next = nullptr;
}

void ListTraverse(LinkList L, void(*vi)(ElemType))
{
	int i = 0;
	if (L)
	{
		LinkList p = L->next;
		while (p)
		{
			vi(p->data);
			p = p->next;
			i++;
			if (!(i % 10))
				cout << endl;
		}
	}
}

Status ListInsert(LinkList &L, int index, ElemType e)
{
	int j = 0;
	LinkList p = L, s;

	while (p && j < index - 1)
	{
		p = p->next;
		j++;
	}

	if (!p || j > index - 1)
		return ERROR;

	if (!(s = (LinkList)malloc(sizeof(LNode))))
		exit(OVERFLOW);
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

Status ListDelete(LinkList &L, int index, ElemType &e)
{
	int j = 0;
	LinkList p = L, q;
	
	while (p->next && j < index - 1)
	{
		p = p->next;
		j++;
	}

	if (!p->next || j > index - 1 )
		return ERROR;

	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	q = nullptr;
	return OK;
}

bool ListEmpty(LinkList L)
{
	if (L->next)
		return false;
	else
		return true;
}

int ListLength(LinkList L)
{
	int i = 0;
	if (L)
	{
		LinkList p = L;
		while (p->next)
		{
			p = p->next;
			i++;
		}
		return i;
	}
	return i;
}

Status GetElem(LinkList L, int index, ElemType &e)
{
	if (index <= 0)
		return ERROR;
	int j = 0;
	LinkList p = L;
	while (p && j < index)
	{
		p = p->next;
		j++;
	}

	if (!p)
		return ERROR;
	e = p->data;
	return OK;
}

int LocateElem(LinkList L, ElemType e)
{
	int i = 0;
	if (L)
	{
		LinkList p = L;
		while (p->next)
		{
			i++;
			p = p->next;
			if (p->data == e)
				return i;
		}
	}	
	return i;
}

/*
//this function is not efficient
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{
	int location = LocateElem(L, cur_e);
	if (location > 1)
	{
		GetElem(L, location - 1, pre_e);
		return OK;
	}
	else
		return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
	int location = LocateElem(L, cur_e);
	if (location >= 1 && location < ListLength(L))
	{
		GetElem(L, location + 1, next_e);
	return OK;
	}
	else
	return ERROR;
}
*/
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{
	if (L)
	{
		LinkList p = L, q = L->next;
		if (!q)
			return ERROR;
		while (q->next)
		{
			p = p->next;
			q = q->next;
			if (q->data == cur_e)
			{
				pre_e = p->data;
				return OK;
			}
		}
		return ERROR;
	}
	return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
	if (L)
	{
		LinkList p = L;
		if (p->next == nullptr)
			return ERROR;
		while (p->next->next)
		{
			p = p->next;
			if (p->data == cur_e)
			{
				next_e = p->next->data;
				return OK;
			}
		}
	}
	return ERROR;
}

void ClearList(LinkList &L)
{
	if (L)
	{
		LinkList p, q;
		p = L->next;
		while (p)
		{
			q = p->next;
			free(p);
			p = q;
		}
		L->next = nullptr;
	}
}

void DestroyList(LinkList &L)
{
	LinkList q;
	while (L)
	{
		q = L->next;
		free(L);
		L = q;
	}
}
//function.h
#ifndef FUNCTION_CPP
#define FUNCTION_CPP

#include"c1.h"
#include"elemtype.h"
using namespace std;

void print(ElemType e)
{
	cout << e << " ";
}

#endif
//main.cpp
#include "c1.h"
#include "c2-2.h"
#include "function.h"
using namespace std;

int main()
{
	LinkList L;
	InitList(L);
	cout << "ListEmpty: " << ListEmpty(L) << endl;
	cout << "ListLength: " << ListLength(L) << endl;
	
	for (int i = 0; i < 100; i++)
		cout << ListInsert(L, i + 1, i);
	cout << endl;
	ListTraverse(L, print);
	cout << "ListEmpty: " << ListEmpty(L) << endl;
	cout << "ListLength: " << ListLength(L) << endl;
	cout << endl;

	ElemType e;
	ListDelete(L, 1, e);
	ListDelete(L, 97, e);
	ListTraverse(L, print);
	cout << endl;

	cout << "ListLength: " << ListLength(L) << endl;

	cout << "GetElem: " << GetElem(L, 98, e);
	cout << " e = " << e << endl;

	cout << "LocateElem: " << LocateElem(L, 99) << endl;

	cout << "PriorElem: " << PriorElem(L, 99, e);
	cout << "  e = " << e << endl;

	cout << "NextElem: " << NextElem(L, 98, e);
	cout << "  e = " << e << endl;

	ClearList(L);
	DestroyList(L);

	cin.get();
	return 0;
}

 

转载于:https://my.oschina.net/kuailechengxuyuan/blog/673206

#include<bits/stdc++.h> using namespace std; struct Plant { //植物信息定义 string name; //植物名称 string sname; //学名 string place[100]; //分布地 string detail; //详情描述 }; typedef struct LNode { Plant data; //结点的数据域 struct LNode *next; //指针域 }LNode,*LinkList; void ReadFile(LinkList& L, string filename) {//从文件中读取数据,存入链表L中 ifstream infile("data_edit/plant.txt"); string line; LinkList r = L; while (getline(infile, line)) { LinkList p = new LNode; Plant temp; stringstream data(line); string s; int flag = 0; while (getline(data, s, '#')) { if (flag == 0) temp.name = s; if (flag == 1) temp.sname = s; if (flag == 2) { stringstream ssplace(s); string place; int placenum = 0; while (getline(ssplace, place, '@')) { temp.place[placenum] = place; placenum++; } } if (flag == 3) temp.detail = s; flag++; } p->data = temp; p->next = r->next; r->next = p; r = p; } infile.close(); return; } int InPlant(LinkList L,string name) {//判断该植物名称name是否存在于链表中 LNode* p = new LNode; p = L->next; int flag = 0; while (p) { if (p->data.name == name) { flag++; } p = p->next; } if (flag > 0) { return true; } else { return false; } } bool InsertPlant(LinkList &L, string filename) {//增加植物信息,输入植物的名称、学名、分布地和详情描述信息,将该植物的基本信息添加到plant.txt中的最后 //如果该植物名称存在于plant.txt中,返回false,否则,返回true int n = 0; string name, sname, place[100], detail; cin >> name; getchar(); getline(cin, sname); cin>> n; for (int i = 0; i < n; i++) { cin >> place[i]; } cin >> detail; if (InPlant(L, name)) { return false; } else { fstream file; file.open(filename, ios::out | ios::app); file << name << "#" << sname << "#"; for (int i = 0; i < n-1; i++) { file<< place[i]<<"@"; } file << place[n - 1] << "#" << detail << endl; } 请保留以上框架,保证正确的情况下,修改部分part: #include <iostream> #include <fstream> #include <string> using namespace std; // 植物节点结构体 struct PlantNode { string name; // 植物名称 string environment; // 生长环境 string use; // 用途 PlantNode* next; // 指向下一个节点的指针 // 构造函数 PlantNode(string n, string e, string u) : name(n), environment(e), use(u), next(nullptr) {} }; class PlantList { private: PlantNode* head; // 链表头指针 const string filename = "plant.txt"; // 数据文件名 public: // 构造函数 PlantList() : head(nullptr) { loadFromFile(); // 初始化时从文件加载数据 } // 从文件加载数据到链表 void loadFromFile() { ifstream file(filename); if (!file) { cerr << "无法打开文件: " << filename << endl; return; } string name, env, use; // 读取每行数据(格式:名称 环境 用途) while (file >> name >> env >> use) { // 跳过空行 if (name.empty()) continue; // 创建新节点并添加到链表 PlantNode* newNode = new PlantNode(name, env, use); if (head == nullptr) { head = newNode; } else { PlantNode* temp = head; while (temp->next != nullptr) { temp = temp->next; } temp->next = newNode; } } file.close(); cout << "已从文件加载 " << countPlants() << " 条植物数据" << endl; } // 添加新植物(自动检查名称重复) bool addPlant(string name, string env, string use) { // 检查名称是否已存在 if (isNameExists(name)) { cout << "添加失败!植物名称 '" << name << "' 已存在" << endl; return false; } // 创建新节点 PlantNode* newNode = new PlantNode(name, env, use); // 添加到链表末尾 if (head == nullptr) { head = newNode; } else { PlantNode* temp = head; while (temp->next != nullptr) { temp = temp->next; } temp->next = newNode; } // 追加到文件 ofstream file(filename, ios::app); if (file) { file << name << " " << env << " " << use << endl; file.close(); cout << "成功添加: " << name << endl; return true; } else { cerr << "无法写入文件" << endl; delete newNode; // 回滚链表修改 return false; } } // 检查名称是否已存在 bool isNameExists(string name) { PlantNode* current = head; while (current != nullptr) { if (current->name == name) { return true; } current = current->next; } return false; } // 统计植物数量 int countPlants() { int count = 0; PlantNode* current = head; while (current != nullptr) { count++; current = current->next; } return count; } // 显示所有植物信息 void displayAll() { cout << "\n当前植物列表:" << endl; cout << "----------------------------------------" << endl; PlantNode* current = head; while (current != nullptr) { cout << "名称: " << current->name << " | 环境: " << current->environment << " | 用途: " << current->use << endl; current = current->next; } cout << "----------------------------------------" << endl; cout << "总计: " << countPlants() << " 种植物" << endl; } // 析构函数(释放链表内存) ~PlantList() { PlantNode* current = head; while (current != nullptr) { PlantNode* next = current->next; delete current; current = next; } } }; // 用户交互界面 int main() { PlantList plantDB; int choice; do { cout << "\n植物管理系统" << endl; cout << "1. 显示所有植物" << endl; cout << "2. 添加新植物" << endl; cout << "3. 退出" << endl; cout << "请选择操作: "; cin >> choice; if (choice == 1) { plantDB.displayAll(); } else if (choice == 2) { string name, env, use; cout << "输入植物名称: "; cin >> name; cout << "输入生长环境: "; cin >> env; cout << "输入用途: "; cin >> use; plantDB.addPlant(name, env, use); } } while (choice != 3); cout << "系统已退出,数据已保存" << endl; return 0; }
最新发布
06-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值