前言
本系列文章是笔者学习数据结构的笔记,如有不妥之处欢迎指正
本文中讲述的大部分链表操作均以单独函数形式表示,仅方便演示,具体使用请结合实际情况
上一篇文章中创建好的链表
int main()
{
int n;
scanf("%d",&n);
struct NODE *head = NULL;
head = creat(n);
display(head);
printf("\n");
sort(head,n);
display(head);
return 0;
}
struct NODE * creat(int n)
{
int i;
struct NODE *head = (struct NODE *)malloc(sizeof(struct NODE));
struct NODE *tail;
tail = head;
tail->Next = NULL;
for(i=0;i<n;i++)
{
struct NODE *t = (struct NODE *)malloc(sizeof(struct NODE));
scanf("%d",&t->data);
tail->Next = t;
t->Next = NULL;
tail = t;
}
return head;
}
判断链表是否为空
if(head->Next = NULL)
return 0;
else
return 1;
计算链表的长度
int len (struct NODE *head)
{
int len = 0;
struct NODE *p = head->Next; //p指向第一个有效节点
while(p != NULL) //只要不为空该节点即为有效节点
{
len++;
p = p->Next; //切换到下一个节点
}
return len;
}
向链表中插入元素
void insert(struct NODE *head)
{
int n;
int i = 0; //S设立一个边界值便于后续判断插入位置是否越界
struct NODE *p = head;
scanf("%d",&n); //输入在第几个节点的前面插入
while(p != NULL && i<n-1) //遍历链表到插入的位置
{
p = p->Next;
i++;
}
if(i>n-1 || p==NULL) //if中的p==NULL是为了处理越界的情况,例如链表一共只有2个节点但是却要求在第4个节点的地方插入
return ; //while循环结束后p的值是第2个节点的Next所指向的地址,即NULL
//i>n-1是为了处理插入位置为负数的情况(如果为负数,),NULL==p为了处理插入位置越界的情况
//以上任意一种情况成立,即错误的插入,停止本函数的运行
struct NODE *new = (struct NODE *)malloc(sizeof(struct NODE));
scanf("%d",&new->data); // 要插入的数
struct NODE *t; //临时节点,用于暂存数据
t = p->Next; //将新节点链接到链表此处
p->Next = new;
new->Next =t;
}
删除链表中的元素
void delete(struct NODE *head)
{
int n;
int i = 0;
struct NODE *p = head;
scanf("%d",&n); //输入要删除第几个节点
while(p->Next != NULL && i<n-1) //注意此处改变为p的下一个节点的指针
{
p = p->Next;
i++;
}
if(i>n-1 || p->Next==NULL) //注意此处改变为p的下一个节点的指针
return ;
struct NODE *t;
t = p->Next;
p->Next = t->Next;
free(t); //释放内存
t = NULL; //情空指针内容
}
链表排序(;´д`)ゞ
- 此处使用冒泡排序法
void sort(struct NODE *head,int len)
{
int i,j;
int t;
struct NODE *a;
struct NODE *p1;
struct NODE *p2;
for (i = 0; i < len - 1; i++)
{
a = head->Next;
for (j = 0; j < len - i - 1; j++)
{
p1 = a;
p2 = a->Next;
if (p1->data > p2->data) //交换它们之间的数据域
{
t = p1->data;
p1->data = p2->data;
p2->data = t;
}
a = a->Next;
}
}
}