本文中链表都是没有头结点的,即头指针指向的结点就存数据,head==NULL链表为空
链表就是一种线性表,优点是不用事先知道要开多少空间、有多少数据,插入删除数据快,相对的,缺点就是不能像数组那样直接访问第i个数据,因此不能快速排序。
一、结点
struct node { int data; //链表中存储的数据 struct node* next; //指向下一个结点 };
二、链表的创建
struct node* Creat(int n) //创建链表 n是数据数 { struct node *head=NULL; struct node *q=NULL; //q保存前驱结点 while(n--) { struct node* p=(struct node*)malloc(sizeof(struct node)); //创建一个新结点并给该结点开空间 scanf("%d",&p->data); p->next=NULL; //初始化新结点的next指针 if(head==NULL) //head==NULL 则该节点是第一个结点 head=p; else q->next=p; //前一个结点的next指向当前结点 q=p; //让q指向新结点,则下次循环q指向的结点就是前一个结点 } return head; //返回头指针,没有头指针我们就找不到链表了 };
三、链表的删除
1.按值删除,删除所有值为x的结点
struct node* Delete(struct node* head,int x) //x是要删除的值 { while(head!=NULL&&head->data==x) //把前面的值为x的结点删除 head=head->next; if(head==NULL) //如果删空了直接return return head; struct node *q=head; //前面的x已经删除了,第一个结点一定不等于x,从头结点的下一个结点开始遍历 while(q!=NULL&&q->next!=NULL) { if(q->next->data==x) q->next=q->next->next; //删除结点 q=q->next; } return head; };
2.删除第pos个结点
struct node* Delete(struct node* head,int pos) //删除第pos个点,从0开始计数 { if(pos==0) return head->next; //如果删除第0个 直接返回指向第1个结点的指针 int num=0; struct node *p=head; while(p!=NULL&&p->next!=NULL) //遍历 { num++; if(num==pos) //当前是第pos个结点,删除并返回 { p->next=p->next->next; return head; } p=p->next; } return head; //循环结束说明链表中结点数小于x,返回头指针 };
四、链表的插入
struct node* Insert(struct node* head,int n,int pos) //在pos位置后插入n { struct node *t=(struct node*)malloc(sizeof(struct node)); t->data=n;t->next=NULL; //创建新结点开空间并初始化 if(pos==0) { if(head!=NULL) { t->next=head; head=t; return head; //如果pos为0,直接插入并返回 } return t; //如果原链表为空链表,直接返回t } struct node *p=head; int num=0; while(p!=NULL) { num++; if(num==pos) { t->next=p->next; p->next=t; return head; } p=p->next; } return head; //没有第pos个结点 插入失败 };
五、链表的排序
因为链表的优势就是插入数据快,所以这里写一个插入排序,其他排序就不写了
struct node* Sort(struct node *head) { if(head==NULL) return head; struct node *Head=head; //Head是排好序后的链表,将剩下的结点插入到Head链表中 head=head->next; Head->next=NULL; while(head!=NULL) { struct node *t=head; //t是剩下的结点中的第一个 head=head->next; struct node *q=NULL; //q指向p的前驱结点 struct node *p=Head; while(p!=NULL&&p->data<t->data) //在Head链表中找到第一个大于等于t->data的结点 { q=p; p=p->next; } t->next=p; if(q==NULL) //q==NULL说明当前点是最小的,要放在第一个 Head=t; else q->next=t; } return Head; };