链表简单使用(打印、删除元素、增加元素)
一、单链表:单链表是最简单的链表,核心就是结构体内存在某成员为该结构体类型指针指向了另一个结构体。
单链表定义如下:
typedef struct list
{
int data;
struct list* next;
}List;
链表的简单使用主要需要注意结尾处指针等边界条件:
1.查找某一元素,需要在查找的判断条件中加入当指针指向NULL时停止的条件否则将访问NULL地址导致出错;
2.增加元素的可以分为增加在第二个位置(复杂度:1)、最后一个位置(复杂度:n)、顺序位置(复杂度:n)。如无必要,优先选择增加在第二个位置。增加元素的函数代码如下:(新建指针,分配内存,加入到链表中)
void insert_list(List* head,int d)
{
List *temp=NULL;
temp=(List*)malloc(sizeof(List));
temp->next=head->next;
temp->data=d;
head->next=temp;
}
3..删除某一元素。删除单链表内某一元素时,需要把被删除元素前一个元素的next指向其下一个,由于增加元素用了malloc,相应的删除还要free(否则内存泄漏)。这两个操作无论谁先进行另一个就无法顺利执行。需要一个临时指针来记录将要被free的结构体内存地址。代码如下:
void delete_list(List* head,int d)
{
List *temp=NULL;
printf("find:%d ",d);
while(head->next!=NULL && head->next->data!=d)
head=head->next;
if(head->next!=NULL && head->next->data==d)
{
printf("%d find and delete\n",d);
temp=head->next;
head->next=head->next->next;
free(temp);
}
else
printf("there is no %d in list\n",d);
}
二、双链表:双链表和单链表差不多,多了一个指向在它之前结构体的指针。
定义如下:
typedef struct doublelist
{
int data;
struct doublelist* next;
struct doublelist* pre;
}DoubleList;
双链表要更加注意链表结尾处的指针为NULL问题:
1.增加元素:由于在增加元素时还需要把后面元素指向前面的指针也改变,就要额外讨论当链表结尾处时产生的问题。看一下最后两行和单链表的不同就明白了。
void insert_doublelist(DoubleList* head,int d)
{
DoubleList *tem=NULL;
tem=(DoubleList*)malloc(sizeof(DoubleList));
tem->next=head->next;
tem->data=d;
tem->pre=head;
head->next=tem;
if(tem->next!=NULL)
tem->next->pre=tem;
}
2.删除元素:因为双链表有两个指针,删除元素就不需要临时的结构体指针了。同样也是要讨论NULL的问题:
void delete_doublelist(DoubleList* head,int d)
{
printf("find:%d ",d);
while(head->next!=NULL && head->next->data!=d)
head=head->next;
if(head->next!=NULL && head->next->data==d)
{
printf("%d find and delete\n",d);
if(head->next->next!=NULL)
{
head->next=head->next->next;
free(head->next->pre);
head->next->pre=head;
}
else
{
free(head->next);
head->next=NULL;
}
}
else
printf("there is no %d in doublelist\n",d);
}
最后,删除元素不能把第一个元素给删了。删了就找不到头在哪了,除非把后面的元素变量名也记下来。