链表的逆置将一个单链表逆置一下头元素不变
void reverse(struct list *ls)//链表逆置
{
if (ls->next == NULL)
return;//只有一个首节点,不需要逆置
if (ls->next->next == NULL)
return;//也不需要逆置
struct list *last = ls->next;//逆置后ls->next就成了最后一个节点了
struct list *pre = ls;//上一个节点的指针
struct list *cur = ls->next;//当前节点的指针这个就是last节点
struct list *next = NULL;//下一个节点的指针
while(cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
ls->next = pre;
last->next = NULL;//这个其实就是ls->next->next=null只不过这样写更加方便些
}
----------------------------------------------------
如上就是将一个单向链表的元素逆置一下,主要思想是不停的当前元素节点之前前驱节点,然后将后继节点赋值给当前节点,把当前节点当成前驱节点,把后继节点当作当前节点
相当于把前驱节点,当前节点,后继节点整体向后移动一个节点单位,只不过后继节点在下一轮的循环中指定的,然后再把当前节点指向前驱节点,就是上一轮的后继节点指向当前节点,然后依次类推不停的循环知道最后一轮中cur等于最后一个节点,然后next=cur->next=null然后将后继节点赋值给当前节点,那么当前节点在下一轮的循环中成了空的
就跳出循环了!
--------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
struct list
{
int data;//数据域
struct list *next;//指针域
};
struct list *create_list()//建立一个节点
{
return calloc(sizeof(struct list), 1);
}
struct list *insert_list(struct list *ls, int n, int data)//在指定位置插入元素
{
struct list *p = ls;
while(p && n--)
{
p = p->next;
}
if (p == NULL)
{
return NULL;//n的位置大于链表节点数
}
struct list *node = create_list();//新建立一个节点
node->data = data;
node->next = p->next;
p->next = node;
return node;
}
int delete_list(struct list *ls, int n)//删除指定位置元素
{
struct list *p = ls;
while(p && n--)
{
p = p->next;
}
if (p == NULL)
{
return -1;//n的位置不合适
}
struct list *tmp = p->next;
p->next = p->next->next;
free(tmp);
return 0;//删除成功
}
int count_list(struct list *ls)//返回链表元素个数
{
struct list *p = ls;
int count = 0;
while(p)
{
count++;
p = p->next;
}
return count;
}
void clear_list(struct list *ls)//清空链表,只保留首节点
{
struct list *p = ls->next;
while(p)
{
struct list *tmp = p->next;
free(p);
p = tmp;
}
ls->next = NULL;//只有首节点,那么首节点的next也应该设置为NULL
}
int empty_list(struct list *ls)//返回链表是否为空
{
if (ls->next)
return 0;
else
return -1;
}
struct list *locale_list(struct list *ls, int n)//返回链表指定位置的节点
{
struct list *p = ls;
while(p && n--)
{
p = p->next;
}
if (p == NULL)
return NULL;
return p;
}
struct list *elem_locale(struct list *ls, int data)//返回数据域等于data的节点
{
struct list *p = ls;
while(p)
{
if (p->data == data)
return p;
p = p->next;
}
return NULL;//没有找到数据域等于data的节点
}
int elem_pos(struct list *ls, int data)//返回数据域等于data的节点位置
{
int index = 0;
struct list *p = ls;
while(p)
{
index++;
if (p->data == data)
return index;
p = p->next;
}
return -1;//没有找到数据域等于data的节点
}
struct list *last_list(struct list *ls)//得到链表最后一个节点
{
struct list *p = ls;
while(p->next)
{
p = p->next;
}
return p;
}
void merge_list(struct list *ls1, struct list *ls2)//合并两个链表,结果放入ls1中
{
//只合并链表的节点,不合并链条头
last_list(ls1)->next = ls2->next;
free(ls2);//链表头不要了
}
void reverse(struct list *ls)//链表逆置
{
if (ls->next == NULL)
return;//只有一个首节点,不需要逆置
if (ls->next->next == NULL)
return;//也不需要逆置
struct list *last = ls->next;//逆置后ls->next就成了最后一个节点了
struct list *pre = ls;//上一个节点的指针
struct list *cur = ls->next;//当前节点的指针这个就是last节点
struct list *next = NULL;//下一个节点的指针
while(cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
ls->next = pre;
last->next = NULL;//这个其实就是ls->next->next=null只不过这样写更加方便些
}
void traverse(struct list *ls)//循环遍历链表
{
struct list *p = ls;
while(p)
{
printf("%d\n", p->data);
p = p->next;//p指向他对应的下一个节点
}
}
int main(void)
{
struct list *first = create_list();//在堆中间创建一个节点
struct list *second = create_list();//在堆中间创建一个节点
struct list *third = create_list();//在堆中间创建一个节点
first->next = second;
second->next = third;
third->next = NULL;//对于链表的最后一个节点,next域一定为NULL
first->data = 1;
second->data = 2;
third->data = 3;
insert_list(first, 1, 10);
insert_list(first, 1, 20);
insert_list(first, 1, 30);
//delete_list(first, 2);
//clear_list(first);
traverse(first);
printf("----------------\n");
printf("count = %d\n", count_list(first));
printf("%d\n", locale_list(first, 3)->data);
printf("data = %d\n", last_list(first)->data);
printf("-----------------------\n");
struct list *first1 = create_list();
int i;
for(i = 0; i < 10; i++)
{
insert_list(first1, 0, i);
}
printf("----------------\n");
merge_list(first, first1);
printf("---------------------\n");
traverse(first);
printf("---------------------\n");
reverse(first);
traverse(first);
return 0;
}