定义结构体
typedef struct _node{
int data;
struct _node *next;
} Node;
单链表插入(尾插法)
void add(Node *head,int i){
Node *p=(Node*)malloc(sizeof(Node)); //创建新节点
p->data=i;
p->next=NULL;
Node *last=head; //尾指针始终指向当前链表的尾节点
while(last->next){
last=last->next;
}
last->next=p;
}
这里我们可以创建一个新的结构体,内容为头指针(始终指向链表的第一个元素),尾指针(始终指向链表的最后一个元素)。
按位插入
void insert_list(Node *head,int i,int value){
Node *PNode=head->next;
Node *p=(Node*)malloc(sizeof(Node));
p->data=value;
int j=1;
while(j<i-1){
PNode=PNode->next;
j++;
}
p->next=PNode->next;
PNode->next=p;
}
按位删除
void delete_list(Node *head,int i){
Node *p=head->next;
Node *pre=head;
int j=1;
while(j<i){
pre=pre->next;
p=p->next;
j++;
}
pre->next=p->next;
free(p);
}
这里我们使用一个前驱指针,记录当前节点的前一个,以防断链。
删除所有值为x的节点
void delete_samevalue(Node *head,int x){
Node *p=head->next,*pre=head,*q;
while(p!=NULL){
if(p->data==x){
q=p;
p=p->next;
pre->next=p;
free(q);
}else{
p=p->next;
pre=pre->next;
}
}
}
从头扫描单链表,pre为p的前驱。如果p的节点值为x,则删除,且p移向下一个节点,否则p和pre都向后移一个节点。
(q可以记录当前p的节点,方便了后续p的移动。)
打印链表
void print_list(Node head){
Node *last;
for(last=head.next;last;last=last->next) //这是比较经典的遍历链表的语句
printf("%d\t",last->data);
printf("\n");
}
以上算法都是引入了头节点的,我们需要在main函数中先创立一个空节点。引入头节点可以给我们带来两个好处:
1.链表第一个位置上的操作与其他操作一致。
2.空表与非空表的处理统一。