链表的操作例程,其中删除和反序会相对复杂一些。
1.首先对于删除例程,可能不存在这个元素,而存在这个元素的链表,需要查找其前驱元素,修改前驱指针,不然没法保存接下来的元素。而且,对于不存在前驱元素(如链表头就是你要删除的元素),需要直接来修改表头。
2.反序操作,在这里给出了2种方案,第一种利用栈本身的属性(先进后出FILO),第二种添加两个指针,加上表头一共三个指针,一个保存对应的节点,另外两个保存连个链表结构(一个为所需要的链表,另一个为剩余的链表)。如下图,p1也就是表头指针,p2指向需要插入的节点,p3来保存剩余的链表,同时需要p2不断迭代,进而不断将节点插入p1表头当中。
//头文件 提供接口
#ifndef _LIST_H
#define _LIST_H
struct listnode
{
int Item; //这里只用数字进行测试
struct listnode *next;
};
typedef struct listnode *ListNode;
void InitList(ListNode *P);
void InsertList(ListNode *P,int Item);
ListNode DeleteList(ListNode P,int Item);
ListNode Find(ListNode P,int Item);
ListNode FindPre(ListNode P,int Num);
ListNode SortList(ListNode P);
ListNode Reverse1(ListNode P);
ListNode Reverse2(ListNode P);
void ShowList(ListNode P);
void Destroy(ListNode P);
#endif
//文件2 接口函数
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
void InitList(ListNode *P)
{
*P=NULL;
}
void InsertList(ListNode *P,int Num) //第一次插入时会修改头指针的值所以需要返回 或者要换成二位指针
{
ListNode tmp,pt;
tmp=(ListNode)malloc(sizeof(struct listnode));
tmp->Item=Num;
tmp->next=NULL;
pt=*P;
if(pt==NULL)
{
*P=tmp;
}
else
{
while(pt->next!=NULL)
{
pt=pt->next;
}
pt->next=tmp;
}
}
ListNode DeleteList(ListNode P,int Num)
{
ListNode tmp,pt;
if(P==NULL)
printf("list is null!\n");
else if(P->Item==Num)
{
tmp=P;
P=P->next;
free(tmp);
}
else
{
tmp=FindPre(P,Num);
if(tmp->next==NULL)
printf("Don't exist %d!\n",Num);
else
{
pt=tmp->next;
tmp->next=tmp->next->next;
free(pt);
}
}
return P;
}
ListNode Find(ListNode P,int Num)
{
ListNode tmp;
tmp=P;
while(tmp!=NULL&&tmp->Item!=Num)
tmp=tmp->next;
return tmp;
}
ListNode FindPre(ListNode P,int Num)
{
ListNode tmp;
tmp=P;
while(tmp->next!=NULL&&tmp->next->Item!=Num)
tmp=tmp->next;
return tmp;
}
ListNode SortList(ListNode P) //链表排序无线循环
{
ListNode first,t,p,q;
if(P==NULL)
{
printf("list is NULL!");
}
else
{
first=P->next;
P->next=NULL;
while(first!=NULL)
{
for(t=first,q=P;(q!=NULL)&&(q->Item<t->Item);p=q,q=q->next)
;
first=first->next; //无序表中节点离开 插入节点进入有序链表
if(q==P)
{
t->next=P;
P=t;
}
else
{
t->next=q;
p->next=t;
}
}
}
return P;
}
ListNode Reverse1(ListNode P)
{
ListNode pt1,pt2;
if(P==NULL)
printf("Nothing could be done!");
else
{
pt1=P->next;
P->next=NULL;
while(pt1!=NULL)
{
pt2=pt1->next;
pt1->next=P;
P=pt1;
pt1=pt2;
}
}
return P;
}
ListNode Reverse2(ListNode P) //用栈结构来反序
{
ListNode stack[100],tmp;
int i=0;
int j=0;
tmp=P;
while(tmp!=NULL)
{
stack[i++]=tmp;
tmp=tmp->next;
} //退出循环时tmp=NULL
while(j<i)
{
stack[j]->next=tmp;
tmp=stack[j];
j++;
}
return tmp;
}
void ShowList(ListNode P)
{
ListNode tmp;
tmp=P;
while(tmp!=NULL)
{
printf("%3d",tmp->Item);
tmp=tmp->next;
}
}
void Destroy(ListNode P)
{
ListNode tmp;
while(P!=NULL)
{
tmp=P->next;
free(P);
P=tmp;
}
}
//main函数入口
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main(void)
{
ListNode head;
InitList(&head);
printf("Insert 4!\n");
InsertList(&head,4);
printf("Insert 1!\n");
InsertList(&head,1);
printf("Insert 5!\n");
InsertList(&head,5);
printf("List like this:");
ShowList(head);
printf("\n");
head=SortList(head);
printf("Sort list:");
ShowList(head);
printf("\n");
head=Reverse1(head);
printf("Reverse1 list:");
ShowList(head);
printf("\n");
head=Reverse2(head);
printf("Reverse2 list:");
ShowList(head);
printf("\n");
printf("Delete 4:");
head=DeleteList(head,4);
ShowList(head);
printf("\n");
printf("Delete 4:");
head=DeleteList(head,4);
ShowList(head);
printf("\n");
Destroy(head);
return 0;
}
实验结果: