这两天很少刷题了,今天主要研究了一下链表的写法,那我就来总结一下。(我也刚研究链表,用词可能不是很到位)
一.什么是链表:简单来说逻辑上是一种线性表,但他的存储方式是无序的。
二.链表有什么用?相比于我们学的数组他逻辑上是一种线性表,但他的存储方式是有序的。这里可以引出一个问题,假设我们向向这个数组的某个特定位置添加一个新元素(或删除某个元素),那么需要将该特定位置之后的所有元素向后移动一个单元(或往前移动一个单元),当数据量非常大的时候效率便十分低下。这时,链表便可以完美的解决这个问题(至于具体原因后面会解释)。
三.怎么用链表?
1.想用好链表,我们必须具备以下几方面知识:指针,指针函数,结构体,malloc关键字。
2.接下来我谈谈我认为的链表:一个链表包括多个小的结构体单元,每一个结构体单元由两部分构成,一部分用来存放变量,另一部分存放一个指针向下一个结构体单元,第一个结构体单元的数据为空,但指针指向第二个结构体单元,最后一个结构体单元的指针指向空(NULL),接下来就是链表每个元素的增加和删除,他只需要借助一个第三方空的结构体指针便可以实现,具体实现方法在后面会讲到。
3.定义和初始化结构体:
using namespace std;
struct Node{
int value;
struct Node* next;
};
int main()
{
int n;
struct Node* head = NULL; //初始化之前先让链表头指向空
head = (struct Node* )malloc(sizeof(struct Node));//为链表头开辟存储单元
cout<<"请输入链表元素总个数:";
cin>>n;
struct Node* p = head;
//链表初始化
cout<<"请输入所有元素:";
while(n--)
{
int a;
scanf("%d",&a);
struct Node* temp;
temp = (struct Node*)malloc(sizeof(struct Node));
temp->value = a;
temp->next = NULL;
p->next = temp;
p = p->next;
}
p = head;
p = p->next;
cout<<"初始化链表:";
while(p)
{
printf("%d ",p->value);
p = p->next;
}
free(head);
return 0;
}
4.插入元素,具体方法有三种(头插法,尾插法,特定位置插入法)
今天我们谈一谈特定位置插入即可,其他两种方法基本如出一辙。
struct Node* insertList(struct Node* head,int value,int n)
{
struct Node* temp = (struct Node* )malloc(sizeof(struct Node));
int i=0;
struct Node* p = head;
while(p)
{
if(i == n)
{
temp->value = value;
temp->next = p->next;
p->next = temp;
i++;
break;
}
else
{
i++;
p=p->next;
}
}
free(temp);
return head;
}
5.删除特定元素(只要看懂了插入,这个更简单,浏览一下思路便可)
struct Node* delNode(struct Node* head,int n)
{
int i=0;
struct Node* p=head;
while(p)
{
if(i == n)
{
p->next = p->next->next;
break;
}
else
{
i++;
p = p->next;
}
}
return head;
}
总结:关于结构体与链表有关的知识只能是自己看着别人的代码满满理解,理解不了便看着别人的代码想着大概思路敲几遍,最终形成一个自己的构建链表的思路。