链表的核心就是指针,初接触可能不太熟悉。不会用就多用,熟能生巧
定义一个结构体类型,其中由数据类型和指针构成。有指针就相当于知道了门牌号,可以依次知道下个元素
typedef struct node{
int data;
struct node *next;
}Node,*LinkList;
链表的初始化,分配内存,判断是否有内存,头结点为空勿忘
LinkList initailList(void) //链表的初始化
{
LinkList list;
list = (LinkList)malloc(sizeof(Node));
if (!list)
printf("无可分配内存\n");
else
{
list->next = NULL; //头结点为空勿忘
printf("初始化成功\n");
return list;
}
}
尾插法创建链表。将数据不断插到尾部,例如:1,5,7,9,11. 输出为:11,9,7,5,1.故想正序输出需要置反
链表节点的插入,判断插入位置是否合法。例如只有五个元素,插入到第8个元素,即为不合法
void insertList(LinkList list, int place, int x)
{
LinkList p = list;
LinkList new_node;
int i = 0;
if (place > n || place < 0)
printf("位置不合法\n");
while(p && i++ < place-1)
{
p = p->next;
}
new_node = (LinkList)malloc(sizeof(Node));
new_node->next = p->next;
p->next = new_node;
new_node->data = x;
}
void deleteList(LinkList list, int place)
{
LinkList p = list, q;
int i = 0;
if (place < 0 || place > n)
printf("删除位置不合法\n");
while(p && i++ < place - 1)
{
p = p->next;
}
q = p->next;
p->next = q->next;
free(q);
}
链表的去重。保留上一节点,然后向后进行遍历,遇到重复单元进行删除即可
void deleteValue(LinkList list)
{
LinkList p, q, r;
p = list->next;
while(p)
{
r = p; //保留上一个节点
while(r->next)
{
if (r->next->data == p->data)
{
q = r->next; //下一个节点
r->next = q->next; //下下个节点覆盖掉上一个
free(q);
}
else
r = r->next; //遍历后续节点
}
p = p->next;
}
}
链表的置反。
void reverseList(LinkList list)
{
LinkList q, p;
if (!list)
printf("无元素\n");
p = list->next;
while(p->next)
{
q = p->next;
p->next = q->next;
q->next = list->next;
list->next = q;
}
}
链表的交叉合并,创建一个新表,将两个进行插入
LinkList combineList(LinkList x, LinkList y)
{
LinkList list = (LinkList)malloc(sizeof(Node));
LinkList p = list, px = x->next, py = y->next;
while(px||py) //归并
{
if (px)
{
p->next = (LinkList)malloc(sizeof(Node));
p = p->next;
p->data = px->data;
px = px->next;
}
if (py)
{
p->next = (LinkList)malloc(sizeof(Node));
p = p->next;
p->data = py->data;
py = py->next;
}
}
p->next = NULL;
return list;
}
链表输出,非空输出即可
void print(LinkList list)
{
LinkList p = list->next;
while(p)
{
printf("%d ", p->data);
p = p->next;
}
putchar('\n');
}
完整的程序及测试代码如下
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *next;
}Node,*LinkList;
int n, m;
LinkList initailList(void) //链表的初始化
{
LinkList list;
list = (LinkList)malloc(sizeof(Node));
if (!list)
printf("无可分配内存\n");
else
{
list->next = NULL; //头结点为空勿忘
printf("初始化成功\n");
return list;
}
}
void createList(LinkList list, int num) //尾插法创建链表
{
printf("请输入值:");
for(int i = 0; i < num; i++)
{
LinkList p;
p = (LinkList)malloc(sizeof(Node));
if (!p)
printf("无可分配的内存\n");
scanf("%d", &p->data);
p->next = list->next;
list->next = p;
}
}
void insertList(LinkList list, int place, int x)
{
LinkList p = list;
LinkList new_node;
int i = 0;
if (place > n || place < 0)
printf("位置不合法\n");
while(p && i++ < place-1)
{
p = p->next;
}
new_node = (LinkList)malloc(sizeof(Node));
new_node->next = p->next;
p->next = new_node;
new_node->data = x;
}
void deleteValue(LinkList list)
{
LinkList p, q, r;
p = list->next;
while(p)
{
r = p; //保留上一个节点
while(r->next)
{
if (r->next->data == p->data)
{
q = r->next; //下一个节点
r->next = q->next; //下下个节点覆盖掉上一个
free(q);
}
else
r = r->next; //遍历后续节点
}
p = p->next;
}
}
void deleteList(LinkList list, int place)
{
LinkList p = list, q;
int i = 0;
if (place < 0 || place > n)
printf("删除位置不合法\n");
while(p && i++ < place - 1)
{
p = p->next;
}
q = p->next;
p->next = q->next;
free(q);
}
LinkList combineList(LinkList x, LinkList y)
{
LinkList list = (LinkList)malloc(sizeof(Node));
LinkList p = list, px = x->next, py = y->next;
while(px||py)
{
if (px)
{
p->next = (LinkList)malloc(sizeof(Node));
p = p->next;
p->data = px->data;
px = px->next;
}
if (py)
{
p->next = (LinkList)malloc(sizeof(Node));
p = p->next;
p->data = py->data;
py = py->next;
}
}
p->next = NULL;
return list;
}
void reverseList(LinkList list)
{
LinkList q, p;
if (!list)
printf("无元素\n");
p = list->next;
while(p->next)
{
q = p->next;
p->next = q->next;
q->next = list->next;
list->next = q;
}
}
void print(LinkList list)
{
LinkList p = list->next;
while(p)
{
printf("%d ", p->data);
p = p->next;
}
putchar('\n');
}
int main(void)
{
LinkList list, otherlist;
int flag, place, num;
list = initailList();
printf("请输入数据个数:");
scanf("%d", &n);
createList(list, n);
reverseList(list);
printf("1.查看链表 2.插入元素 3.删除位置\n");
printf("4.置反 5.删除元素 6.合并链表 7.退出\n");
while(scanf("%d", &flag) && flag != 7)
{
switch(flag)
{
case 1: print(list); break;
case 2: printf("请输入要插入的位置和值:");scanf("%d %d", &place, &num);insertList(list, place, num);print(list); break;
case 3: printf("请输入要删除的位置:");scanf("%d", &num); deleteList(list, num);print(list); break;
case 4: printf("置反后\n\n");reverseList(list);print(list);break;
case 5: printf("输入删除的元素\n");deleteValue(list); print(list); break;
case 6: printf("创建另一个链表\n");otherlist = initailList();printf("请输入数据个数:");scanf("%d", &m);createList(otherlist, m);
reverseList(otherlist);list = combineList(list, otherlist);print(list);break;
default: printf("操作不合法\n");break;
}
}
return 0;
}