我相信编程是通过多练多写。
链表确实我很爱的一种数据结构。
主要是因为刚开始有不懂,看别人的程序来模仿,而现在可以自如的写出来,所以又开一贴来存储自己的成长之路。
有错误希望提醒。谢谢!
后面的几个删除功能暂时没写上,印证了那句今日事没有今日毕的话了,昨晚写一晚上没能坚持写完,所以现在又不想写。。。
#include <stdio.h>
#include <stdlib.h>
/************************************************************************/
/** 以下是关于线性表链接存储(单链表)操作的18种算法 */
/** 1.初始化线性表,即置单链表的表头指针为空 */
/** 2.创建线性表,此函数输入负数终止读取数据*/
/** 3.打印链表,链表的遍历*/
/** 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
/** 5.返回单链表的长度 */
/** 6.检查单链表是否为空,若为空则返回1,否则返回0 */
/** 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
/** 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
/** 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
/** 10.向单链表的表头插入一个元素 */
/** 11.向单链表的末尾添加一个元素 */
/** 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
/** 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
/* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
/* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
/* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
/* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
/* 18.交换2个元素的位置 */
/* 19.将线性表进行快速排序 */
/************************************************************************/
typedef struct Node
{
int data;
struct Node *pNext;
}Node;
/** 1.初始化线性表,即置单链表的表头指针为空 */
void Linklist_Init(Node **p)
{
printf("这里是链表初始化,初始化中...\n");
(*p) = (Node*)malloc(sizeof(Node));
if((*p) == NULL)
{
printf("链表初始化失败\n");
exit(0);
}
(*p)->pNext = NULL;
printf("链表初始化完成\n");
printf("Linklist_Init()执行完毕\n");
}
/** 2.创建线性表,此函数输入负数终止读取数据*/
void Linklist_Create(Node *L)
{
printf("这里是链表创建,创建中...\n");
Node *p;
Node *_node;
int x;
if(!L)
{
printf("链表为空\n");
exit(0);
}
p = L;
while(p->pNext)
p = p->pNext; //找到尾节点
scanf("%d",&x);
while(x != -1) //输入-1结束链表创建
{
_node = (Node*)malloc(sizeof(Node));
_node->data = x;
_node->pNext = p->pNext; // _node->pNext = NULL;
p->pNext = _node;
p = _node;
scanf("%d",&x);
}
}
/** 3.打印链表,链表的遍历*/
void Linklist_Print(Node *L)
{
printf("这里是链表打印,打印中...\n");
if(!L)
{
printf("链表为空\n");
exit(0);
}
L = L->pNext;
while(L)
{
printf("%d\n",L->data);
L = L->pNext;
}
}
/** 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
void Linklist_Clear(Node *L)
{
printf("这里是链表清空,清空中...\n");
Node *p;
if(!L)
{
printf("链表为空\n");
exit(0);
}
while(L)
{
p = L->pNext;
free(L);
L = p;
}
printf("链表已经清空\n");
}
/** 5.返回单链表的长度 */
int Linklist_Length(Node *L)
{
int i=0;
printf("这里是链表测长中,测长中...\n");
if(!L)
{
printf("链表不存在\n");
return 0;
}
L = L->pNext; //头结点不能算在内
while(L)
{
i++;
L = L->pNext;
}
return i;
}
/** 6.检查单链表是否为空,若为空则返回1,否则返回0 */
void Linklist_Empty(Node *L)
{
printf("这里是链表测空,测空中...\n");
if(!L)
{
printf("链表不存在\n");
exit(0);
}
if(L->pNext==NULL)
printf("链表为空\n");
else
printf("链表不空\n");
}
/** 7.返回单链表中第pos个结点中的元素,并用e返回,若pos超出范围,则停止程序运行 */
void Linklist_Getpos(Node *L,int pos,int *e)
{
int i=1;
printf("这里是链表返回数据,返回pos中...\n");
if( pos>Linklist_Length(L))
{
printf("pos点超出链表长度\n");
exit(0);
}
if(!L)
{
printf("链表不存在\n");
exit(0);
}
L = L->pNext;
while(L)
{
if(i==pos)
{
*e = L->data;
}
L = L->pNext;
i++;
}
printf("小e把数据带回去了\n");
}
/** 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
int* Linklist_Getdata(Node *L,int x)
{
printf("这里是链表返回data,返回中...\n");
if(!L)
{
printf("链表不存在\n");
exit(0);
}
L = L->pNext;
while(L->pNext)
{
if(L->data == x)
{
printf("数据地址已返回\n");
return &(L->data);
}
else
printf("数据不存在...\n");
return NULL;
L = L->pNext;
}
}
/** 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
int Linklist_Repos(Node *L,int pos,int x)
{
int i=1;
printf("这里是链表修改第pos个数据,修改中...\n");
if( pos>Linklist_Length(L))
{
printf("pos点超出链表长度\n");
exit(0);
}
if(!L)
{
printf("链表不存在\n");
exit(0);
}
L = L->pNext;
while(i != pos)
{
L = L->pNext;
i++;
}
if(i==pos)
{
printf("链表第%d个数 原来为:%d 修改为:%d\n",pos,L->data,x);
L->data = x;
return 1;
}
else
{
printf("修改失败!!!\n");
return 0;
}
}
/** 10.向单链表的表头插入一个元素 x*/
void Linklist_InsertHead(Node *L)
{
Node *p;
printf("这里是链表插入头,插入中...\n");
int x;
if(!L)
{
printf("链表不存在\n");
exit(0);
}
printf("请输入插入的数:\n");
scanf("%d",&x);
p = (Node*)malloc(sizeof(Node));
p->data = x;
p->pNext = L->pNext;
L->pNext = p;
printf("x插入完毕,返回...\n");
}
/** 11.向单链表的末尾添加一个元素 */
void Linklist_InsertEnd(Node *L)
{
Node *p,*q;
printf("这里是链表插入尾,插入中...\n");
int x;
if(!L)
{
printf("链表不存在\n");
exit(0);
}
q = L;
printf("请输入插入的数:\n");
scanf("%d",&x);
q = q->pNext;
while(q->pNext)
{
q = q->pNext;
} //使q指向尾节点
p = (Node*)malloc(sizeof(Node));
p->data = x;
p->pNext = q->pNext;//NULL
q->pNext = p;
printf("x插入完毕,正在返回...\n");
}
/** 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
void Linklist_InsertPos(Node* L,int pos)
{
int i;
Node *p,*q;
printf("这里是链表插入pos点,插入中...\n");
q = L;
q = q->pNext;
for(i=0;i<pos-1;i++)
{
q = q->pNext;
}
p = (Node*)malloc(sizeof(Node));
p->pNext = q->pNext;
q->pNext = p;
printf("pos插入完毕,正在返回...\n");
}
/** 20.把单链表翻转*/
Node* Linklist_Turn(Node *L)
{
Node *new_head,*p;
printf("这里是链表翻转,翻转中...\n");
new_head = (Node*)malloc(sizeof(Node));
new_head->pNext = NULL;
p = L = L->pNext;//头指针
while(L)
{
p = p->pNext;
L->pNext = new_head->pNext;
new_head->pNext = L;
L = p;
}
return new_head;
}
int main()
{
int len,e;
int *x;
Node* head = NULL;
Linklist_Init(&head);
Linklist_Create(head);
Linklist_Print(head);
len = Linklist_Length(head);
printf("链表长度为:%d\n",len);
Linklist_Empty(head);
Linklist_Getpos(head,4,&e);
printf("e = %d\n",e);
x=Linklist_Getdata(head,12);
if(x!=NULL)
printf("x = %d\n",*x);
Linklist_Repos(head,4,520);
Linklist_InsertHead(head);
Linklist_InsertEnd(head);
head = Linklist_Turn(head);
Linklist_Print(head);
Linklist_Clear(head);
Linklist_Empty(head);
return 0;
}