如果我们现在有一组数,[1,2,3,4,5,6,7,8,9,10],需要剔除里面的某一个数的时候,可以用循环的方法剔除,但是效率不高,这个时候可以采用链表的方法
0.数组的剔除
有一种解决方法,就是数组的剔除,找出要剔除的下标,然后把后面的元素前移,这种情况下,如果剔除的元素在数组的开头,这样复杂度会非常高,导致设计出来的运行结果缓慢。
按值查询节点
1.链表的创建
1.0定义
定义结构体
typedef struct LNode {
int val;
struct LNode* next;
}LNode, *LinkList;
1.1 初始化
LNode* initLNode()
{
LNode* p = (LNode*)malloc(sizeof(LNode));//创建一个头结点
LNode* temp = p;//声明一个指针指向头结点,用于遍历链表
int num;
printf("请输入链表长度\n");
scanf_s("%d",&num);
for (int i = 1; i < num; i++)
{
LNode* a = (LNode*)malloc(sizeof(LNode));
a->val = i;
a->next = NULL;
temp->next = a;
temp = temp->next;
}
return p;
}
1.2 插入数据
插入数据有两种 头部插入法 还有尾部插入法,这里展示头部插入法
LNode* initLNode()
{
LNode* p = (LNode*)malloc(sizeof(LNode));//创建一个头结点
LNode* temp = p;//声明一个指针指向头结点,用于遍历链表
int num;
printf("请输入链表长度\n");
scanf_s("%d",&num);
for (int i = 1; i < num; i++)
{
LNode* a = (LNode*)malloc(sizeof(LNode));
a->val = i;
a->next = NULL;
temp->next = a;
temp = temp->next;
}
return p;
}
2. 链表的剔除
剔除的方法=找到哪个节点+删掉结点并重新把链表组装好
节点的查询:有按值查询,有按照节点的位置查询
若剔除P1,分为两种:将p2的结构体里面的指向下一个节点的地址,指向P1的下一个,这样子就绕开了P1,最后再把p1释放掉,就完成了剔除
还有一种方法是把P1的值赋值给P2,然后把P2的指向后驱节点等于P1的后驱节点,然后释放P1
LNode* delElem(LinkList p, int add)
{
LNode* temp = p;
//遍历到被删除结点的上一个结点
for (int i = 1; i < add; i++)
{
temp = temp->next;
}
LNode* del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
free(del);//手动释放该结点,防止内存泄漏
return p;
}
2.2 打印到控制台
void display(LinkList p)
{
LNode* temp = p;//将temp指针重新指向头结点
//只要temp指针指向的结点的next不是Null,就执行输出语句。
while (temp->next) {
temp = temp->next;
printf("%d", temp->val);
}
printf("\n");
}
3. 主函数调用
int main()
{
LNode* p = initLNode();
display(p);
printf("在第4的位置插入元素5:\n");
p = insertElem(p, 5, 4);
display(p);
printf("删除元素3:\n");
p = delElem(p, 3);
display(p);
return 0;
}