链表实现
算法
狭义的算法:与数据的存储方式密切相关
广义的算法:与数据的存储方式无关
泛型
(给你一种假象,只不过牛人从内部都弄好了)
利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的
算法的真正学法:
很多算法你根本解决不了!!!!!!因为很多都属于数学上的东西,所以我们把答案找出来,如果能看懂就行。
但是大部分人又看不懂,分三步走
1.梳理流程
2.搞懂每一个语句功能
3.试数,拿数据进行推理,
这个过程肯定会不断地出错,所以不断出错,不断改错,这样反复敲很多次,才能有个提高。极端情况下,实在看不懂就先背会。
链表的优缺点:
优点:
空间没有限制
插入删除元素很快
缺点:
存取速度很慢。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<stdbool.h>
typedef struct Node
{
int data;
struct Node * pNext;
}NODE, * PNODE;
//创建链表,此处使用的是尾插法,还有一种类似的头插法
PNODE creat_list()
{
int len = 0;
int i = 0;
int val = 0;
PNODE pHead = (PNODE) malloc(sizeof(NODE));
if(NULL == pHead)
{
printf("malloc err!\n");
exit(-1);
}
PNODE pTail = pHead;
pTail->pNext = NULL;
printf("请输入您需要创建的链表节点的个数:len = ");
scanf("%d",&len);
for(i = 0; i < len; i++)
{
printf("请输入第%d个节点的数据:val = ",i+1);
scanf("%d",&val);
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL == pNew)
{
printf("分配失败,程序终止!\n");
exit(-1);
}
pNew->data = val;
pTail->pNext = pNew;
pNew->pNext = NULL;//这句其实没必要,只需要创建完成在尾节点指针域赋值为NULL即可
pTail = pNew;
}
//pTail->pNext = NULL;//尾节点指针为空
return pHead;
}
//判断链表是否为空
bool is_empty(PNODE pHead)
{
if(NULL == pHead->pNext)
return true;
else
return false;
}
//遍历链表并输出
void traverse_list(PNODE pHead)
{
if(is_empty(pHead))
{
printf("链表为空!\n");
return;
}
PNODE p = pHead->pNext;
while(p != NULL)
{
printf("%d\t", p->data);
p = p->pNext;
}
printf("\n");
return;
}
//求链表长度
int length_list(PNODE pHead)
{
PNODE p = pHead;
int i = 0;
while(p->pNext != NULL)
{
i++;
p = p->pNext;
}
return i;
}
//链表排序
void sort_list(PNODE pHead)
{
PNODE p,q;
int t;
int i,j;
for(i = 0, p = pHead->pNext; i < len, p != NULL; i++, p = p->pNext)
for(i = j+1, q = p->pNext; j < len, q != NULL; j++, q = q->pNext)
{
if(p->data > q->data)//a[i] > a[j]
{
t = p->data; //t = a[i];
p->data = q->data;//a[i] = a[j];
q->data = t; //a[j] = t;
}
}
return;
}
//插入节点,特别注意while中与删除节点的区别
//插入节点while判断使用的是p,因为即使是链表为空,只有头结点,也可以在头结点后插入一个节点
//删除节点while判读使用的是p->pNext,因为链表为空的时候,没有节点可以删除
int insert_list(PNODE pHead, int pos, int val)
{
int i;
PNODE p = pHead;
//首先调整p指向的位置,
while(NULL != p && i < pos - 1)//注意此处用的是p
{
p = p->pNext;
i++;
}
//这时候p已经指向pos的位置
if(i > pos-1 || p == NULL)
return false;
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL == pNew)
{
printf("分配内存失败!\n");
exit(-1);
}
pNew->data = val;
PNODE q = p->pNext;
p->pNext = pNew;
pNew->pNext = q;
return true;
}
int delete_list(PNODE pHead, int pos, int *val)
{
int i = 0;
PNODE p = pHead;
while (NULL!=p->pNext && i<pos-1)//此处使用的p->pNext
{
p = p->pNext;
++i;
}
if (i>pos-1 || NULL==p->pNext)
return false;
PNODE q = p->pNext;
*val = q->data;
p->pNext = q->pNext;
free(q);
return true;
}
int main(void)
{
PNODE pHead;
pHead = creat_list();
traverse_list(pHead);
//if(is_empty(pHead))
// printf("list is empty!\n");
printf("list length:%d\n",length_list(pHead));
sort_list(pHead);
traverse_list(pHead);
int ret;
/* ret = insert_list(pHead, 1, 11);
if(ret < 0)
{
printf("插入失败,ret = %d\n",ret);
return -1;
}
traverse_list(pHead);*/
int val;
int pos;
printf("请输入您要删除的节点位置pos(pos从1开始): ");
scanf("%d",&pos);
ret = delete_list(pHead, pos, &val);
if(ret != 1)
printf("删除失败!\n");
else
printf("删除节点数据:val %d\n",val);
traverse_list(pHead);
return 0;
}