单向链表的节点创建和头插、尾插、任意位置插入节点的实现
今天复习了链表的知识,决定通过自己的理解直接手撕代码,不去参考已经写过的链表代码,在不断的调试中,总算写出来了同时发现对指针和单向链表有了更深的理解。
实现代码:
//单向链表
struct Node //用结构体作为链表的节点
{
Node *next; //用于存储下一个节点的地址
string data; //用于存储数据
};
typedef struct Node* List; //为了简化书写和可读性,将struct Node* 命名为 List
//头节点的创建 不用于存储数据,只是为了作为链表首节点的地址
//bool init(List &head) <==> bool init(Node* &head) <==> bool init(List *head)
//参数为 Node* head 这是一个指针指向一个结构体,现在将它作为参数传递,涉及实参和形参的问题,需要改变这个指针则传入的参数就必须是该指针的地址,即指针的指针,二级指针,或者使用C++的引用
bool init(List &head)
{
List newnode = new Node; //动态创建一个节点
if (nullptr == newnode) //判断节点是否创建成功
{
cout << "new failed!" << endl;
return false;
}
newnode->next = nullptr; //因为是单向链表,所以尾部指向nullptr
newnode->data = " "; //头节点的数据不存储,但进行以下初始化
head = newnode; //将创建的节点赋给头节点
return true;
}
//头插法:在链表首部插入数据,注意头节点只是指示作用,所以头插法,应该是插入在头节点的后面,首个数据节点的前面
bool insert_head(List head, string value)
{
List newnode = new Node; //动态创建一个节点的内存
if (nullptr == newnode)
{
cout << "new failed!" << endl;
return false;
}
newnode->data = value; //将数据赋给创建节点
//将创建的节点插入到链表中
newnode->next = head->next; //节点的下一个应为头节点的下一个 即首数据的节点
head->next = newnode; //头节点的下一个即为创建的节点,此时完成了节点的插入
return true;
}
//任意位置插入法
bool insert_index(List head, int index, string value)
{
List temp = head; //需要保存头节点的位置
int count = 0;
while (temp->next->next != nullptr) //计算出链表总过有几个节点,用于判断传入位置的参数是否合法
{
++count;
temp = temp->next;
}
if (index >= 0 && index <= count)
{
temp = head;
for (int i = 0; i < index; ++i) //定位到要插入的节点
{
temp = temp->next;
}
List newnode = new Node;
if (nullptr == newnode)
{
cout << "new failed!" << endl;
return false;
}
newnode->data = value;
newnode->next = temp->next; //进行插入操作
temp->next = newnode;
}
else
{
cout << "out of range!!!" << endl;
return false;
}
return true;
}
//尾插法
//尾插法即插入的节点插入到最后一个,即它的下一个指向nullptr 原本最后一个元素的下一个指向它
bool insert_tail(List head, string value)
{
List newnode = new Node;
if (nullptr == newnode)
{
cout << "new failed!" << endl;
return false;
}
newnode->data = value;
//进行尾插
newnode->next = nullptr; //节点的下一个为nullptr
while (head->next != nullptr) //寻找到尾节点
{
head = head->next;
}
head->next = newnode; //将尾节点的下一个指向创捷的节点
return true;
}
//打印所有节点
void display(List head)
{
while (head->next != nullptr)
{
cout << head->next->data << " ";
head = head->next;
}
cout << endl;
}
测试程序:
int main()
{
List head = nullptr;
init(head);
//尾插法
for (int i = 0; i < 10; i++)
{
insert_tail(head, "hello");
}
cout << "尾插法后: ";
display(head);
//头插法
insert_head(head, "haha");
cout << "头插法后: ";
display(head);
insert_index(head, 4, "zhou");
cout << "指定位置插入插法后: ";
display(head);
system("pause");
return 0;
}
运行结果: