做为一个调包侠,长期用现成的轮子干活,已经严重限制了个人编程水平的提升。所以想要从本质上提升自己的编程水平,还是要抽时间自己造轮子。虽然说现在语言越来越高级,轮子越来越丰富,但是内功心法才是成才之道。
链表做为基础的线性结构,很多复杂的数据结构基本由其演变而来,因此有必要熟练掌握。
实现代码如下:
# include<iostream>
using namespace std;
struct Node{
int a;
Node *next;
};
// 创建链表
Node* create_list(Node *head, Node *tail){
int list_len = 0;
Node *node = new Node; // 创建链表第一个结点
head = node;
head->a = 0;
tail = head;
cout << "Enter list len: " << endl;
cin >> list_len;
for (int i = 1;i<list_len;i++){
int element = 0;
Node *node = new Node;
tail->next = node; // 将上一个结点的next指针指向当前结点
cout << "Enter element: " << endl;
cin >> element;
node->a = element;
if (head!=NULL){
tail = node; // 将当前结点赋值给tail
}
}
return head;
}
// 求链表长度
int list_len(Node *p){
int len = 0;
while(1){
p = p->next;
len += 1;
if (p==NULL)
break;
}
return len;
}
// 向链表中插入元素
void insert_node(Node *p, int index, int value){
int len = list_len(p);
Node *node = new Node;
node->a = value;
for (int i = 0;i<len;i++){
if (i==index-1){
node->next = p->next;
p->next = node;
break;
}
}
}
// 删除链表中元素
void delete_node(Node *p, int index){
int len = list_len(p);
for (int i = 0;i<len;i++){
if (i==index-1){
delete p->next; // 释放该处结点内存地址
p->next = p->next->next;
break;
}
}
}
// 查找第n个元素所在结点
Node* find_node(Node *p, int k){
int len = list_len(p);
for (int i = 0;i < len-k;i++){
p = p->next;
}
return p;
}
// 遍历链表
void print_list(Node *p){
while(1){
cout << p->a << " ";
p = p->next; // 指针指向下一个结点
if (p==NULL){
break;
}
}
cout << endl;
}
int main(){
Node *head = NULL;
Node *tail = NULL;
Node *p = create_list(head, tail);
print_list(p);
Node *q = find_node(p, 2);
cout << q->a << endl;
insert_node(p, 2, 100);
print_list(p);
delete_node(p, 2);
print_list(p);
return 0;
}
由于长期调包,直接使用比较高级的数据结构,所以在对指针的理解和运用上存在偏差。导致实现了个链表也花费了不少精力,主要是难点是在思维的坎上,当思维顺畅以后,发现其实也并没有那么难了,原本想总结点什么规律,却发现都是小儿科,也就没什么好废话的了。
代码运行结果如下: