qq_43717446
努力学习的阿信
2021-05-21 16:30
采纳率: 40%
浏览 27

VS2019运行报错 fatal error LNK1120

#ifndef _LS_LinkList_H_
#define _LS_LinkList_H_
#include<iostream>
template<class Type>
class LinkNode {			//节点类
public:
	Type data;
	LinkNode* next;			//指针next用来链接节点
	LinkNode();
	~LinkNode();
};

template<class Type>
class LinkList {			//链表类
private:
	int length;
public:
	LinkList();
	void InitList(LinkNode<Type>*& L);									//建立头节点
	void CreateList(LinkNode<Type>*& L, Type arr[], int& len);			//头插法建立循环单链表
	bool ListEmpty(LinkNode<Type>*& L);									//判断循环单链表是否为空
	int ListLength(LinkNode<Type>*& L);									//获取循环单链表长度
	void DispList(LinkNode<Type>*& L) const;							//输出循环单链表
	bool GetElem(LinkNode<Type>*& L, int& locate, Type& e);				//按照输入的数值查找循环单链表
	bool LocateList(LinkNode<Type>*& L, Type& e, int& locate);			//按照输入的元素值查找循环单链表
	bool InsertList(LinkNode<Type>*& L, int& locate, Type& e);			//将指定元素插入到执行位置
	bool DeleteList(LinkNode<Type>*& L, int& locate, Type& e);			//删除指定位置的元素并使用e接收要删除的元素值
	void DestoryList(LinkNode<Type>*& L) const;							//销毁循环单链表
	~LinkList();
};

#endif
#include<iostream>
#include "LSLinkList.h"

template<class Type>
LinkNode<Type>::LinkNode()
{
	//啥都不做
}
template<class Type>
LinkNode<Type>::~LinkNode()
{
	//啥也不做
}

template<class Type>
LinkList<Type>::LinkList() 
{
	length = 0;//初始值设置为零
	std::cout << "构造函数建立循环单链表对象完成!" << std::endl;
}
template<class Type>
void LinkList<Type>::InitList(LinkNode<Type>*& L)
{
	L = new LinkNode<Type>;
	L->next = L;							//将节点L的指针next指向自身
	std::cout << "InitList建立头节点完成!" << std::endl;
}
template<class Type>
void LinkList<Type>::CreateList(LinkNode<Type>*& L, Type arr[], int& len)
{
	LinkNode<Type>* pre = L, * s;
	int i;
	length = len;							//获取双链表的长度
	for (i = 0;i < len;i++) {
		s = new LinkNode<Type>;				//动态申请节点的存储空间
		s->data = arr[i];
		s->next = L->next;					//将节点s插入到循环单链表上
		L->next = s;
	}
	std::cout << "CreateList建立循环单链表完成!" << std::endl;
}
template<class Type>
bool LinkList<Type>::ListEmpty(LinkNode<Type>*& L)
{
	//返回值true说明节点L的next指针指向节点L本身,因此链表为空,否则非空
	return (L->next == L);
}
template<class Type>
int LinkList<Type>::ListLength(LinkNode<Type>*& L)
{
	return length;
}
template<class Type>
void LinkList<Type>::DispList(LinkNode<Type>*& L) const
{
	LinkNode<Type>* pre = L;
	while (pre->next != L) {//找到链表中最先插入的节点pre
		pre = pre->next;
		std::cout << pre->data << "  ";
	}
	std::cout << "\n";//换行并清空缓冲区的内容
	if (L->next == pre) //这是判断单链表是否还有其它节点
		std::cout << "DispList检测到单链表此时只有一个头节点,无法输出!" << std::endl;
	else//单链表只有一个头节点
		std::cout << "DispList输出循环链表完成!" << std::endl;
}
template<class Type>
bool LinkList<Type>::GetElem(LinkNode<Type>*& L, int& locate, Type& e)
{
	LinkNode<Type>* pre = L;
	int i = 0;
	if (locate <= 0) {
		std::cout << "GetELem检测到违法输入!" << std::endl;
		return false;
	}
	while (i <= length - locate ) {//将逻辑位置转换为单链表中的位置
		i++;
		pre = pre->next;
	}
	if (length - locate < 0) {//未查询到节点pre,查询越界(pre->next==L)
		std::cout << "GetElem未查询到结果(越界)!" << std::endl;
		return false;
	}
	else //此时在链表中查询到该节点pre(i>length-locate)
	{
		e = pre->data;								//使用元素e接收查询的值
		std::cout << "GetElem查询成功!" << std::endl;
		return true;
	}
}
template<class Type>
bool LinkList<Type>::LocateList(LinkNode<Type>*& L, Type& e, int& locate)
{
	LinkNode<Type>* pre = L;
	int i = 0;
	while (pre->data != e && pre->next != L) {//该节点的data数据域存放的不是e,该节点不是最后一个节点
		i++;
		pre = pre->next;
	}
	if (pre->next == L) {//已经查询到最后一个节点
		std::cout << "LocateList查询链表失败!(越界)" << std::endl;
		return false;
	}
	else				//说明在链表中查询到元素e
	{
		locate = length - i + 1;//元素的逻辑位置和在链表中的真实位置满足:逻辑位置+链表存储位置 = length+1
		std::cout << "LocateList查询链表成功!" << std::endl;
		return true;
	}
}
template<class Type>
bool LinkList<Type>::InsertList(LinkNode<Type>*& L, int& locate, Type& e)//将元素e插入到指定位置
{
	LinkNode<Type>* pre = L, * s;
	int i = 0;
	if (locate <= 0) {
		std::cout << "InsertList检测到违法输入!" << std::endl;
		return false;			//返回函数调用点
	}
	while (i <= length - locate) {//逻辑位置转换成链表中的实际位置,判断是否越界
		i++;
		pre = pre->next;
	}
	if (length - locate < 0) {//如果输入的locate位置比链表长度length大,说明插入位置越界,无法插入
		std::cout << "InsertList插入失败(越界)!" << std::endl;
		return false;
	}
	else
	{
		s = new LinkNode<Type>;	//动态申请存储空间
		s->data = e;
		s->next = pre->next;	//节点s插入到单链表中
		pre->next = s;
		length++;				//插入成功后更新循环链表长度
		std::cout << "InsertList插入节点成功!" << std::endl;
		return true;
	}
}
template<class Type>
bool LinkList<Type>::DeleteList(LinkNode<Type>*& L, int& locate, Type& e)
{
	LinkNode<Type>* pre = L, * s = L->next;
	int i = 0;
	if (locate <= 0) {
		std::cout << "DeleteList检测到违法输入!" << std::endl;
		return false;			//返回函数调用点
	}
	while (i < length - locate) {//逻辑位置转换成链表中的实际位置,判断是否越界
		i++;
		pre = pre->next;
		s = s->next;
	}
	if (length - locate < 0) {//若此时输入的locate小于链表长度,说明链表发生越界,删除失败
		std::cout << "DeleteList插入失败(越界)!" << std::endl;
		return false;
	}
	else//说明已经找到要删除的节点
	{
		pre->next = s->next;//删除这个节点
		e = s->data;
		delete s;
		length--;//删除后更新循环链表的长度
		std::cout << "DeleteList删除节点成功!" << std::endl;
		return true;
	}
}
template<class Type>
void LinkList<Type>::DestoryList(LinkNode<Type>*& L) const
{
	LinkNode<Type>* pre = L -> next;
	while (L->next != L) {				//判断节点L的下一个节点是否为L
		L->next = pre->next;			//L的next指针指向要删除的节点的下一个节点
		delete pre;						//删除节点并将指针pre重置指向节点L的下一个节点
		pre = L->next;
	}
	delete L;
	std::cout << "DestoryList销毁链表成功!" << std::endl;
}
template<class Type>
LinkList<Type>::~LinkList<Type>()
{
	std::cout << "析构函数释放循环单链表对象!" << std::endl;
}
#include<iostream>
#include "LSLinkList.h"

int main() {
	using std::cout;
	using std::endl;
	LinkNode<int>* L;
	LinkList<int> obj;
	int arr[]{ 1,2,3,4,5,7,8,9,10 };
	int len = sizeof(arr) / sizeof(arr[0]);//获取数组的长度
	int length = 0;

	obj.InitList(L);				//测试InitList函数接口的功能,同时获取此时链表的状态信息
	length = obj.ListLength(L);
	cout << "此时的循环链表长度length为:" << length << endl;
	int BOOL = obj.ListEmpty(L);
	cout << "ListEmpty的值为0说明链表非空,为1说明链表为空!" << endl;
	cout << "BOOL = " << BOOL << endl;
	obj.DispList(L);
	cout << endl;

	obj.CreateList(L, arr, len);		//测试CreateList函数接口功能,同时获取此时链表的状态信息
	length = obj.ListLength(L);
	cout << "ListLength获取链表长度length为:" << length << endl;
	BOOL = obj.ListEmpty(L);
	cout << "ListEmpty的值为0说明链表非空,为1说明链表为空!" << endl;
	cout << "BOOL = " << BOOL << endl;
	obj.DispList(L);
	cout << endl;

	int locate = 0, e = 0;			//测试GetElem函数接口
	locate = 7;
	obj.GetElem(L, locate, e);
	cout << "GetElem查询单链表后查找到的元素e值为:" << e << "\n\n";

	locate = 0, e = 8;					//按照元素e的值查询循环单链表
	obj.LocateList(L, e, locate);		//测试LocateList函数接口
	cout << "LocateList查询单链表后的locate值为:" << locate << "\n\n";

	locate = 6, e = 6;					//将元素6插入到链表的指定位置(逻辑位置)
	obj.InsertList(L, locate, e);
	len = obj.ListLength(L);
	cout << "此时ListLength获取的链表长度length为:" << len << endl;
	obj.DispList(L);
	cout << endl;

	locate = 10, e = 0;					//删除链表中指定位置的元素
	obj.DeleteList(L, locate, e);		//测试DeleteList函数接口
	cout << "DeleteList删除的节点值e为:" << e << endl;
	len = obj.ListLength(L);
	cout << "此时ListLength获取的链表长度length为:" << len << endl;
	obj.DispList(L);
	cout << endl;

	obj.DestoryList(L);
	return 0;
}

这是我在实现循环单链表基本算法是遇到的问题,我刚开始做的时候都是放在VS2019同一个源文件做的,运行成功后我就开始将源文件改成多文件实现,就是函数及 类的生命放在头文件中,函数实现放在单独一个cpp文件,然后建立一个main.cpp文件执行main函数,但是这时候本来就能成功运行的程序报错,显示fatal error LNK1120:12个无法解析的错误,数量正好是函数实现源文件cpp里的函数个数,不知道什么情况,请各位指点一下迷津!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • BostonRayAlen
    bostonAlen 2021-05-21 16:42
    已采纳
    点赞 评论
  • qq_43717446
    努力学习的阿信 2021-05-21 16:32

    点赞 评论
  • qq_43717446
    努力学习的阿信 2021-05-21 17:25

    点赞 评论

相关推荐