本系列博客 以C语言为实现语言 个人总结,请持怀疑态度参考
要点总结
- 头插
要考虑到插入的是第一个节点的情况- 链表的删除节点的动作
要考虑到链表有没有节点- 按值插入
按值插入在链表中的数据是有序的时候差有意义- 排序
链表的排序一般不是以数据为单位,而是以节点为单位。排序的过程可以转化为值不停的插入的过程。即把链表拆分为两个链表,一个链表中只有头节点,把另一个链表中的数据按值插入第一个链表中。- 逆置
这个思路还是把链表拆开成两个链表 ,第一个链表除了头结点只有一个节点,第二个链表就是剩下的部分。然后把第二个链表的值依次插入到第一个链表的头结点之后。- 迭尾代器
用迭代器的方法实现头插/尾插会更加简单。- 按值删除
按值删除的思路有两中 ,一种是找到值的节点,让后把节点的后驱的值拷贝过来,让后删除后驱,相当于删除了节点,避免了需要寻找值的前驱;第二种是通过节点的next的节点的值比较,找到节点的前驱,剩下的就好办了。。
贴一下完整的C实现以及注释
//Slist.h 文件
#ifndef _SLIST_H_
#define _SLIST_H_
#include <stdio.h>
#include <malloc.h>
#include "assert.h"
#define ElemType int
typedef struct Node
{
ElemType data;
struct Node * next;
}Node,*PNode;
typedef struct List
{
PNode first;
PNode last;
size_t size;
}List;
Node *creatNode();
void InitList(List *);
void push_back(List * mylist, ElemType x);
void push_front(List *mylist, ElemType x);
void show_list(List *mylist);
void pop_back(List *mylist);
void pop_front(List *mylist);
void insert_val(List *mylist,ElemType x);
Node *find(List *mylist, ElemType x);
size_t length(List *mylist);
bool delete_val(List *mylist, ElemType x);
void sort(List *mylist);
void resver(List *mylist);
void clear(List *mylist);
void destroy(List *mylist);
/***********************************/
/*迭代器算法*/
typedef Node * Iter;
Iter begin(List *list);
Iter end(List *list);
void insert(List list, Iter pos, ElemType x);
#endif
----------
//Slist.c 文件
#include "Slist.h"
Node * creatNode()
{
Node * node = (Node*)malloc(sizeof(Node));
assert(node != NULL);
return node;
}
void InitList(List * list)
{
list->first = list->last =(Node*)malloc(sizeof(Node));
assert(list->first != NULL);
list->size = 0;
list->first->next = NULL; //考虑到在一个空链表头插的情况
}
void push_back(List * mylist, ElemType x)
{
Node* s=creatNode();
s->data = x;
s->next = NULL;
mylist->last->next = s;
mylist->last = s;
mylist->size++;
return;
}
void push_front(List *mylist, ElemType x)
{
Node *s = creatNode();
s->data = x;
s->next = mylist->first->next;
mylist->first->next = s;
mylist->size++;
if (mylist->size==0) //考虑到插入的是地一个节点
{
mylist->last = s;
}
return;
}
void show_list(List *mylist)
{
Node *p = mylist->first->next; //头结点是没有数据的,头节点的第二个节点才有数据
while (p!=NULL)
{
printf("%d-->", p->data);
p = p->next;
}
printf("end\n");
return;
}
void pop_back(List *mylist)
{
if (mylist->size==0) //如果链表为空
{
return;
}
Node *p = mylist->first;
while (p->next != mylist->last)
{
p = p->next;
}
free(mylist->last);
mylist->last = p;
mylist->last->next = NULL;
mylist->size--;
}
void pop_front(List *mylist)
{
if (mylist->size == 0) //如果链表为空
{
return;
}
Node *p = mylist->first->next; //保存第一个节点
mylist->first->next = mylist->first->next->next;
free(p);
p = NULL;
mylist->size--;
if (mylist->size==0) //如果把最后一个节点删了,就要考虑尾节点
{
mylist->last = mylist->first;
}
return;
}
void insert_val(List *mylist, ElemType x)
{
Node * s = creatNode();
s->data = x;
s->data = NULL;
Node*p = mylist->first;
while (p->next!=NULL &&p->next->data<x)
{
p = p->next;
}
if (p->next==NULL) //考虑到插在最后一个节点
{
mylist->last = s;
}
s->next = p->next;
p->next = s;
mylist->size++;
}
Node * find(List *mylist, ElemType x)
{
Node *p = mylist->first->next;
while (p!=NULL&&p->data==x) //这里注意 判断条件的执行顺序 先判断p是不是NULL
{
p = p->next;
}
return p; //p其实包含了两种结果 p=NULL p->data=x
}
size_t length(List *mylist)
{
return mylist->size;
}
bool delete_val(List *mylist, ElemType x)
{
if (mylist->size==0)
{
return false;
}
// Node *p = mylist->first->next;
// while (p->next!=NULL&&p->next->data==x)
// {
// p=p->next;
// }
// if (p->next!=NULL)
// {
// Node *pp = p->next;
// p->next = p->next->next;
// free(pp);
// if (p->next==NULL)
// {
// mylist->last = p;
// }
// mylist->size--;
// return true;
// }
// else
// {
// return false;
// }
Node *p = find(mylist, x);
if (p!=NULL)
{
if (p==mylist->last) //如果最后一个节点
{
pop_back(mylist);
}
else
{
Node* q = p->next;
p->data = q->data;
p->next = p->next->next;
free(q);
mylist->size--;
}
return true;
}
else
{
return false;
}
}
void sort(List *mylist)
{
if (mylist->size <= 1)
{
return;
}
Node *s = mylist->first->next;
Node *q = s->next;
mylist->last = s;
mylist->last->next = NULL;
while (q!=NULL)
{
s = q;
q = q->next;
Node*p = mylist->first;
while (p->next != NULL &&p->next->data < s->data)
{
p = p->next;
}
if (p->next == NULL) //考虑到插在最后一个节点
{
mylist->last = s;
}
s->next = p->next;
p->next = s;
mylist->size++;
}
}
void resver(List *mylist)
{
if (mylist->size <= 1)
{
return;
}
Node *s = mylist->first->next;
Node *q = s->next;
mylist->last = s;
mylist->last->next = NULL;
while (q!=NULL)
{
s = q;
q = q->next;
s->next = mylist->first->next;
mylist->first->next = s;
}
return;
}
void clear(List *mylist)
{
if (mylist->size==0)
{
return;
}
Node *p = mylist->first->next;
while (p!=NULL)
{
mylist->first->next = p->next;
free(p);
p = mylist->first->next;
}
mylist->last = mylist->first;
mylist->size = 0;
return;
}
void destroy(List *mylist)
{
clear(mylist);
free(mylist->first);
mylist->first = mylist->last = NULL;
}
/********************************************/
Iter begin(List *list)
{
return list->first->next;
}
Iter end(List *list)
{
return list->last->next;
}
void insert(List *list, Iter pos, ElemType x)
{
Node *p = list->first;
while (p->next!=pos)
{
p = p->next;
}
Node *s = creatNode();
s->data = x;
s->next = p->next;
p->next = s;
if (pos==NULL)
{
list->last = s;
}
}
----------
//main.c
#include "Slist.h"
int main()
{
List myList;
InitList(&myList);
Node *p = NULL;
int select = 1;
while (select)
{
printf("**********************************************\n");
printf("*[1]push_back [2]push_front*\n");
printf("*[3]show_list [4]pop_back *\n");
printf("*[5]pop_front [6]insert_val*\n");
printf("*[7]find [8]length *\n");
printf("*[9]delete_val [10]sort *\n");
printf("*[11]resver [12]clear *\n");
printf("*[13]destory [0]quit *\n");
printf("**********************************************\n");
printf("请选择:>");
scanf_s("%d", &select);
switch (select)
{
case 1:
int a;
printf("请输入要插入的数据(-1结束):>");
while (scanf_s("%d",&a))
{
if (a==-1)
{
break;
}
push_back(&myList, a);
}
break;
case 2:
break;
case 3:
show_list(&myList);
break;
case 4:
pop_back(&myList);
break;
case 5:
pop_front(&myList);
break;
case 6:
printf("请输入要插入的数据:>");
scanf_s("%d", &a);
insert_val(&myList, a);
break;
case 7:
printf("请输入要查找的数据");
scanf_s("%d", &a);
p = find(&myList, a);
if (p==NULL)
{
printf("数据不存在\n");
}
break;
case 8:
printf("单链表的长度:> %d\n", length(&myList));
break;
case 9:
printf("请输入要删除的值> ");
scanf_s("%d", &a);
if (!delete_val(&myList, a))
{
printf("删除失败!");
}
break;
case 10:
sort(&myList);
show_list(&myList);
break;
case 11:
resver(&myList);
break;
case 12:
clear(&myList);
case 13:
destroy(&myList);
default:
break;
}
}
getchar();
return 0;
}
我的个人网站 http://www.breeziness.cn/
我的CSDN http://blog.csdn.net/qq_33775402转载请注明出处 小风code www.breeziness.cn