数据结构与算法分析(二)——C++实现链表

虽然实现了,但不是特别好。。。

思路

1.由于数据来源于文件,故选择在读入数据时建立链表进行存储
2.List中存放公有变量head用来存放链表头的地址,List_length存放链表长度,构造函数初始化时直接将建立完成的链表的表头赋给head

//List.h
#pragma once
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;

struct node
{
	string address;
	string number;
	string time;
	node* next;
};

class List
{
public:
	List(node* head_ptr,int number);//构造函数,初始化头指针和链表长度
	~List(void);
	void Print_List();//打印链表
	void Insert_Node(int posi,string address,string number,string time);//插入节点
	void Delete_Node(int posi);//删除节点
	int Find_Node_index(int count,string address,string number,string time);//查找节点
	node* head;//头指针
	int List_length;//链表长度
};

3.插入操作时,遍历指针迭代到指向第posi-1个节点,此时在第posi-1个节点和第posi个节点之间插入新节点。如果插入的是头节点,则需要新操作,因为没有0-1节点。
4.删除操作时,遍历指针同样迭代到指向第posi-1个节点,此时将第posi-1个节点的后向节点变成第posi+1个节点,并利用delete删除第posi个节点。
5.查找节点时,选择查找的方向,输入查找的内容。

//List.cpp
#include "List.h"

List::List(node* head_ptr,int number)
{
	head=head_ptr;
	List_length=number;
}

List::~List(void)
{
	node* temp_curr=head;
	node* temp_next=NULL;

	while(temp_curr!=NULL)
	{
		temp_next=temp_curr->next;
		delete temp_curr;
		temp_curr=temp_next;
	}
}

/**
 *@name Print_List:打印链表
 *@ret:None
**/
void List::Print_List()
{
	node* temp=head;
	for (int i=0;i<List_length;i++)
	{
		//打印出一个节点的三个数据
		cout<<temp->address<<" "<<temp->number<<" "<<temp->time<<endl;
		//指针指向下一个指针
		temp=temp->next;
	}
}

/**
 *@name Insert_List:插入一个节点
 *@param1 address:节点的第一个数据-地址
 *@param2 number:节点的第二个数据-序号
 *@param3 time:时间
**/
void List::Insert_Node(int posi,string address,string number,string time)
{
	//定义一个遍历指针
	node* temp=head;
	if(posi<0)
	{
		cout<<"error,index<0"<<endl;
		return;
	}

	//插入新的节点
	for (int i=0;i<posi-1;i++)
	{
		temp=temp->next;
	}
	//此时已经temp指向了第posi-1个节点
	//创建一个新的节点
	node* new_node=new node;
	new_node->address=address;
	new_node->number=number;
	new_node->time=time;

	//如果在头部加入,则需要重新确定头部,否则头部指针将指向第一个节点
	if(posi==0)
	{
		head=new_node;
		new_node->next=temp;
	}
	else
	{
		//在新节点后面挂上原来第posi个节点以及后面的节点
		new_node->next=temp->next;
		//第posi个节点由新的节点代替
		temp->next=new_node;
	}

	//节点个数自加1
	List_length++;
}

/**
 *@name Delete_Node:删除节点
 *@param1 posi:所要删除的节点的位置
**/
void List::Delete_Node(int posi)
{
	//定义一个遍历指针
	node* temp=head;
	node* temp_del;
	if(posi<0)
	{
		cout<<"error,index<0"<<endl;
		return;
	}

	//删除节点
	for (int i=0;i<posi-1;i++)
	{
		temp=temp->next;
	}
	//此时遍历指针来到了posi-1的节点
	if(posi==0)
	{
		head=temp->next;
		delete temp;
	}
	else
	{
		//将第posi个节点删除
		temp_del=temp->next;
		temp->next=temp->next->next;
		//释放内存
		delete temp_del;
	}

	//节点个数自减1
	List_length--;
}


/**
 *@name Find_Node_index:查找节点中数据对应的索引号
 *@param1  count:查找的值 1-地址 2-序号 3-时间
 *@param2 add:查找的地址值
 *@param3 num:查找的序号
 *@param4 t:查找的时间
**/
int List::Find_Node_index(int count,string add,string num,string t)
{
	node* temp=head;
	int i;
	//查找address
	if(count==1)
	{
		for (i=0;i<List_length;i++)
		{
			if((temp->address)==add)
				break;
			temp=temp->next;
		}
		if(i!=List_length)
			return i;
		else
		{
			cout<<"not found address"<<endl;
			return -1;
		}
	}

	//查找number
	else if(count==2)
	{
		for (i=0;i<List_length;i++)
		{
			if((temp->number)==num)
				break;
			temp=temp->next;
		}
		if(i!=List_length)
			return i;
		else
		{
			cout<<"not found number"<<endl;
			return -1;
		}
	}

	//查找时间
	else if(count==3)
	{
		for (i=0;i<List_length;i++)
		{
			if((temp->time)==t)
				break;
			temp=temp->next;
		}
		if(i!=List_length)
			return i;
		else
		{
			cout<<"not found time"<<endl;
			return -1;
		}
	}
}

6.读文件代码与之前类似

//main.cpp
#include <fstream>
#include "List.h"

/**
 *@name Readfile:从文本中读入数据,以链表形式存储
 *@param1 * head_ptr:指向链表头部的指针
 *@param2 filename:文件名
 *@ret:链表的头指针
**/
node* Readfile(string filename)
{
	node* head_ptr;
	node* temp;
	ifstream in(filename,ios::in);
	temp=new node;
	head_ptr=temp;
	for (int i=0;i<500;i++)
	{
		//创建链表
		in>>temp->address;
		in>>temp->number;
		in>>temp->time;
		temp->next=new node;
		temp=temp->next;
	}
	temp->next=NULL;
	return head_ptr;
}

void main()
{
	node* temp;
	List li(Readfile("500.txt"),500);
	li.Insert_Node(2,"asd","1","2");
	//li.Delete_Node(0);
	//cout<<li.Find_Node_index(1,"asd","1","2")<<endl;
	li.Print_List();
	system("pause");
}

其他思路

来源老师PPT,对于List,没有像我一样使用List_length去存储链表的长度,直接用节点的next是否指向了NULL进行判断。
他这也是从0开始计的节点数。。。

Node* List::InsertNode(int index, double x) 
{
	if (index < 0) return NULL;
	int currIndex = 1;
	Node* currNode = head;
	//索引初始值设为1,currNode会迭代到index处
	while (currNode && index > currIndex)
	{
		currNode = currNode->next;
		currIndex++;
	}
	if (index > 0 && currNode == NULL) return NULL;
	Node* newNode = new Node;
	newNode->data = x;
	if (index == 0)
	{
		newNode->next = head;
		head = newNode;
	}
	//在第index个节点后面插入
	else 
	{
		newNode->next = currNode->next;
		currNode->next = newNode;
	}
	return newNode;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值