[英]Simple linked list in C++
我即将创建一个可以插入和显示的链接,直到现在:
struct Node {
int x;
Node *next;
};
这是我的初始化函数,只会为第一个Node
调用:
void initNode(struct Node *head, int n){
head->x = n;
head->next = NULL;
}
要添加Node
,我认为我的链表无法正常工作的原因在于这个函数:
void addNode(struct Node *head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
我的main
功能:
int _tmain(int argc, _TCHAR* argv[])
{
struct Node *head = new Node;
initNode(head, 5);
addNode(head, 10);
addNode(head, 20);
return 0;
}
让我按照我认为可行的方式运行该程序。 首先,我将头Node
初始化为这样的Node
:
head = [ 5 | NULL ]
然后我添加一个 n = 10 的新节点并将 head 作为我的参数传递。
新节点 = [ x | next ] next 指向头部。 然后我更改 head 指向 NewNode 的位置,因为 NewNode 现在是 LinkedList 中的第一个节点。
为什么这不起作用? 我将不胜感激任何可以使我朝着正确方向前进的提示。 我认为 LinkedList 有点难以理解。
当我打印这个时,它只返回 5:
这是我能想到的最简单的例子,没有经过测试。 请注意,这使用了一些不好的做法,并且与您通常使用 C++ 的方式不同(初始化列表、声明和定义的分离等)。 但这是我无法在此涵盖的主题。
#include <iostream>
using namespace std;
class LinkedList{
// Struct inside the class LinkedList
// This is one node which is not needed by the caller. It is just
// for internal work.
struct Node {
int x;
Node *next;
};
// public member
public:
// constructor
LinkedList(){
head = NULL; // set head to NULL
}
// destructor
~LinkedList(){
Node *next = head;
while(next) { // iterate over all elements
Node *deleteMe = next;
next = next->next; // save pointer to the next element
delete deleteMe; // delete the current entry
}
}
// This prepends a new value at the beginning of the list
void addValue(int val){
Node *n = new Node(); // create new Node
n->x = val; // set value
n->next = head; // make the node point to the next node.
// If the list is empty, this is NULL, so the end of the list --> OK
head = n; // last but not least, make the head point at the new node.
}
// returns the first element in the list and deletes the Node.
// caution, no error-checking here!
int popValue(){
Node *n = head;
int ret = n->x;
head = head->next;
delete n;
return ret;
}
// private member
private:
Node *head; // this is the private member variable. It is just a pointer to the first Node
};
int main() {
LinkedList list;
list.addValue(5);
list.addValue(10);
list.addValue(20);
cout << list.popValue() << endl;
cout << list.popValue() << endl;
cout << list.popValue() << endl;
// because there is no error checking in popValue(), the following
// is undefined behavior. Probably the program will crash, because
// there are no more values in the list.
// cout << list.popValue() << endl;
return 0;
}
我强烈建议您阅读一些有关 C++ 和面向对象编程的内容。 一个好的起点可能是这样的: http : //www.galileocomputing.de/1278?GPP=opoo
编辑:添加了一个弹出功能和一些输出。 如您所见,程序推送 3 个值 5、10、20,然后弹出它们。 之后顺序颠倒,因为此列表在堆栈模式下工作(LIFO,后进先出)
你应该参考一个头指针。 否则指针修改在函数外部不可见。
void addNode(struct Node *&head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
这两个函数都是错误的。 首先,函数initNode
有一个容易混淆的名字。 它应该命名为例如initList
并且不应该执行 addNode 的任务。 也就是说,它不应向列表中添加值。
其实函数initNode没有任何意义,因为在定义head时就可以完成列表的初始化:
Node *head = nullptr;
或者
Node *head = NULL;
因此,您可以从列表设计中排除函数initNode
。
此外,在您的代码中,无需为结构Node
指定详细的类型名称,即在名称Node
之前指定关键字 struct 。
函数addNode
将改变 head 的原始值。 在您的函数实现中,您只更改作为参数传递给函数的 head 副本。
该函数可能如下所示:
void addNode(Node **head, int n)
{
Node *NewNode = new Node {n, *head};
*head = NewNode;
}
或者,如果您的编译器不支持初始化的新语法,那么您可以编写
void addNode(Node **head, int n)
{
Node *NewNode = new Node;
NewNode->x = n;
NewNode->next = *head;
*head = NewNode;
}
或者,您可以使用对指向 Node 的指针的引用,而不是使用指向指针的指针。 例如,
void addNode(Node * &head, int n)
{
Node *NewNode = new Node {n, head};
head = NewNode;
}
或者你可以从函数返回一个更新的头部:
Node * addNode(Node *head, int n)
{
Node *NewNode = new Node {n, head};
head = NewNode;
return head;
}
并在main
写:
head = addNode(head, 5);
我会加入战斗。 好久没写C了,再说了,这里也没有完整的例子。 OP 的代码基本上是 C 语言,所以我继续使用 GCC 使其工作。
问题在前面已经介绍过了; next
指针没有被推进。 这是问题的关键。
我也借此机会进行了建议的编辑; 而不是有两个funcitons到malloc
,我把它放在initNode()
然后使用initNode()
来malloc
两者( malloc
是“C新型”如果你愿意)。 我更改了initNode()
以返回一个指针。
#include <stdlib.h>
#include <stdio.h>
// required to be declared before self-referential definition
struct Node;
struct Node {
int x;
struct Node *next;
};
struct Node* initNode( int n){
struct Node *head = malloc(sizeof(struct Node));
head->x = n;
head->next = NULL;
return head;
}
void addNode(struct Node **head, int n){
struct Node *NewNode = initNode( n );
NewNode -> next = *head;
*head = NewNode;
}
int main(int argc, char* argv[])
{
struct Node* head = initNode(5);
addNode(&head,10);
addNode(&head,20);
struct Node* cur = head;
do {
printf("Node @ %p : %i\n",(void*)cur, cur->x );
} while ( ( cur = cur->next ) != NULL );
}
编译: gcc -o ll ll.c
输出:
Node @ 0x9e0050 : 20
Node @ 0x9e0030 : 10
Node @ 0x9e0010 : 5
下面是一个示例链表
#include <string>
#include <iostream>
using namespace std;
template<class T>
class Node
{
public:
Node();
Node(const T& item, Node<T>* ptrnext = NULL);
T value;
Node<T> * next;
};
template<class T>
Node<T>::Node()
{
value = NULL;
next = NULL;
}
template<class T>
Node<T>::Node(const T& item, Node<T>* ptrnext = NULL)
{
this->value = item;
this->next = ptrnext;
}
template<class T>
class LinkedListClass
{
private:
Node<T> * Front;
Node<T> * Rear;
int Count;
public:
LinkedListClass();
~LinkedListClass();
void InsertFront(const T Item);
void InsertRear(const T Item);
void PrintList();
};
template<class T>
LinkedListClass<T>::LinkedListClass()
{
Front = NULL;
Rear = NULL;
}
template<class T>
void LinkedListClass<T>::InsertFront(const T Item)
{
if (Front == NULL)
{
Front = new Node<T>();
Front->value = Item;
Front->next = NULL;
Rear = new Node<T>();
Rear = Front;
}
else
{
Node<T> * newNode = new Node<T>();
newNode->value = Item;
newNode->next = Front;
Front = newNode;
}
}
template<class T>
void LinkedListClass<T>::InsertRear(const T Item)
{
if (Rear == NULL)
{
Rear = new Node<T>();
Rear->value = Item;
Rear->next = NULL;
Front = new Node<T>();
Front = Rear;
}
else
{
Node<T> * newNode = new Node<T>();
newNode->value = Item;
Rear->next = newNode;
Rear = newNode;
}
}
template<class T>
void LinkedListClass<T>::PrintList()
{
Node<T> * temp = Front;
while (temp->next != NULL)
{
cout << " " << temp->value << "";
if (temp != NULL)
{
temp = (temp->next);
}
else
{
break;
}
}
}
int main()
{
LinkedListClass<int> * LList = new LinkedListClass<int>();
LList->InsertFront(40);
LList->InsertFront(30);
LList->InsertFront(20);
LList->InsertFront(10);
LList->InsertRear(50);
LList->InsertRear(60);
LList->InsertRear(70);
LList->PrintList();
}
addNode
函数需要能够改变head
。 正如现在所写的那样,只需更改局部变量head
(一个参数)。
将代码更改为
void addNode(struct Node *& head, int n){
...
}
将解决这个问题,因为现在head
参数是通过引用传递的,被调用的函数可以改变它。
head
在 main 中定义如下。
struct Node *head = new Node;
但是您只是在addNode()
和initNode()
函数中更改头部。 更改不会反映回主要内容。
将 head 声明为全局并且不要将其传递给函数。
功能应该如下。
void initNode(int n){
head->x = n;
head->next = NULL;
}
void addNode(int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode->next = head;
head = NewNode;
}
用:
#include<iostream>
using namespace std;
struct Node
{
int num;
Node *next;
};
Node *head = NULL;
Node *tail = NULL;
void AddnodeAtbeggining(){
Node *temp = new Node;
cout << "Enter the item";
cin >> temp->num;
temp->next = NULL;
if (head == NULL)
{
head = temp;
tail = temp;
}
else
{
temp->next = head;
head = temp;
}
}
void addnodeAtend()
{
Node *temp = new Node;
cout << "Enter the item";
cin >> temp->num;
temp->next = NULL;
if (head == NULL){
head = temp;
tail = temp;
}
else{
tail->next = temp;
tail = temp;
}
}
void displayNode()
{
cout << "\nDisplay Function\n";
Node *temp = head;
for(Node *temp = head; temp != NULL; temp = temp->next)
cout << temp->num << ",";
}
void deleteNode ()
{
for (Node *temp = head; temp != NULL; temp = temp->next)
delete head;
}
int main ()
{
AddnodeAtbeggining();
addnodeAtend();
displayNode();
deleteNode();
displayNode();
}
我认为,为了确保列表中每个节点的深度链接, addNode
方法必须是这样的:
void addNode(struct node *head, int n) {
if (head->Next == NULL) {
struct node *NewNode = new node;
NewNode->value = n;
NewNode->Next = NULL;
head->Next = NewNode;
}
else
addNode(head->Next, n);
}
在一段代码中有一个错误:
void deleteNode ()
{
for (Node * temp = head; temp! = NULL; temp = temp-> next)
delete head;
}
有必要这样:
for (; head != NULL; )
{
Node *temp = head;
head = temp->next;
delete temp;
}
这是我的实现。
#include <iostream>
using namespace std;
template< class T>
struct node{
T m_data;
node* m_next_node;
node(T t_data, node* t_node) :
m_data(t_data), m_next_node(t_node){}
~node(){
std::cout << "Address :" << this << " Destroyed" << std::endl;
}
};
template<class T>
class linked_list {
public:
node<T>* m_list;
linked_list(): m_list(nullptr){}
void add_node(T t_data) {
node<T>* _new_node = new node<T>(t_data, nullptr);
_new_node->m_next_node = m_list;
m_list = _new_node;
}
void populate_nodes(node<T>* t_node) {
if (t_node != nullptr) {
std::cout << "Data =" << t_node->m_data
<< ", Address =" << t_node->m_next_node
<< std::endl;
populate_nodes(t_node->m_next_node);
}
}
void delete_nodes(node<T>* t_node) {
if (t_node != nullptr) {
delete_nodes(t_node->m_next_node);
}
delete(t_node);
}
};
int main()
{
linked_list<float>* _ll = new linked_list<float>();
_ll->add_node(1.3);
_ll->add_node(5.5);
_ll->add_node(10.1);
_ll->add_node(123);
_ll->add_node(4.5);
_ll->add_node(23.6);
_ll->add_node(2);
_ll->populate_nodes(_ll->m_list);
_ll->delete_nodes(_ll->m_list);
delete(_ll);
return 0;
}
这只是一个示例,而不是链接列表的完整功能,代码中解释了附加功能和打印链接列表
代码 :
#include<iostream>
using namespace std;
节点类
class Node{
public:
int data;
Node* next=NULL;
Node(int data)
{
this->data=data;
}
};
名为 ll 的链接列表类
class ll{
public:
Node* head;
ll(Node* node)
{
this->head=node;
}
void append(int data)
{
Node* temp=this->head;
while(temp->next!=NULL)
{
temp=temp->next;
}
Node* newnode= new Node(data);
// newnode->data=data;
temp->next=newnode;
}
void print_list()
{ cout<<endl<<"printing entire link list"<<endl;
Node* temp= this->head;
while(temp->next!=NULL)
{
cout<<temp->data<<endl;
temp=temp->next;
}
cout<<temp->data<<endl;;
}
};
主功能
int main()
{
cout<<"hello this is an example of link list in cpp using classes"<<endl;
ll list1(new Node(1));
list1.append(2);
list1.append(3);
list1.print_list();
}
thanks ❤❤❤
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.