代码改变世界

链表基本功能

2015-08-20 19:18  1784717631  阅读(338)  评论(0编辑  收藏  举报

  链表虽然也是线性表,但是相比于顺序表,让人操的心却不是同一个等级的,小小一道题目都可以分分钟虐死大半自信,昨晚憋了一个晚上的插入排序,虽然知道算法,奈何敌人太过于狡猾(指针渣渣。。)。早上几乎把链表的基本操作都做了一遍,指针指的飞起。。。

  下午曹老师给我讲解了下插入排序(还好自己没有继续搞下去,,),这种高深复杂的实现,小白还是从模仿开始的好啊,自己很难挤出来,浪费时间不说,自信真的所剩无几了,不多说,一下是一天的劳动成果

 

 

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct _node
{
int data;
struct _node *next;
}node_t;

typedef struct linklist
{
node_t *head;
node_t *tail;
int length;
}linklist_t;

linklist_t* init_lklist(linklist_t *plklist)
{
plklist->head=NULL;
plklist->tail=NULL;
plklist->length=0;
return (plklist);
}


int head_inser_lklist(linklist_t *plklist, node_t *pnew)
{
if(plklist->head==NULL)
{
plklist->head = pnew;
plklist->tail = pnew;
plklist->length++;
}
else
{
pnew->next = plklist->head;
plklist->head = pnew;
plklist->length++;
}
}

int middle_inser_lklist(linklist_t *plklist, int pos, int val)//瑕佸湪绗簩涓綅缃紑濮嬫彃鍏?
{
int i=1;
node_t *p = plklist->head;

if(pos == 1 || pos == 0)
{
node_t *pnew = (node_t *)malloc(sizeof(node_t *)); //鎶婁紶杩涙潵 鐨勬暟鎹皝瑁呮垚鑺傜偣锛屾敞鎰忚鍒嗛厤绌洪棿
pnew->data = val;
head_inser_lklist(plklist, pnew);
return 0;
}

while(p != NULL && i <pos-1) //绉诲姩娲诲姩鑺傜偣鍒皃os浣嶇疆鐨勫墠涓€涓?
{
p = p->next;
i++;
}
if( i<pos-1 ||p==NULL ) //鍒ゆ柇鏄惁瓒婄晫
{
printf("insert error !\n");
exit(-1);
}

node_t *pnew = (node_t *)malloc(sizeof(node_t *)); //鎶婁紶杩涙潵 鐨勬暟鎹皝瑁呮垚鑺傜偣锛屾敞鎰忚鍒嗛厤绌洪棿
pnew->data = val;

node_t *q = p->next; //瀹氫箟鏂拌妭鐐规寚鍚憄鐨勪笅涓€涓妭鐐?

pnew->next = q; //鎻掑叆鎿嶄綔
p->next = pnew;

return 0;
}

int tail_inser_lklist(linklist_t *plklist, node_t *pnew)
{
if(plklist->head==NULL)
{
plklist->head = pnew;
plklist->tail = pnew;
plklist->length++;
}
else
{
plklist->tail->next = pnew;
plklist->tail = pnew;
plklist->length++;
}
return 0;
}
int delete_lklist(linklist_t *plklist, int pos)//瑕佸湪绗簩涓綅缃紑濮嬫彃鍏?
{
int i=1;
node_t *p = plklist->head;

if(pos == 1 ||pos == 0) //删除第一个元素独立处理
{
plklist->head = plklist->head->next;
p->next = NULL;
}
else
{
while(p != NULL && i <pos-1) //绉诲姩娲诲姩鑺傜偣鍒皃os浣嶇疆鐨勫墠涓€涓?
{
p = p->next;
i++;
}
if( i<pos-1 ||p==NULL ) //鍒ゆ柇鏄惁瓒婄晫
{
printf("delete error !\n");
exit(-1);
}


p->next = p->next->next;
}
return 0;
}

int delete_same(linklist_t *plklist)
{
node_t *p1 = NULL;
node_t *p2 = NULL;
node_t *p3 = NULL; //p3 用来存放相等的节点

p1 = plklist->head;
p2 = plklist->head; //开始p1 p2都指向头节点

while(p1 != NULL) //外循环
{
while(p2->next !=NULL) //内循环
{
if(p1->data == p2->next->data)
{
p3 = p2->next; //p3指向相等的节点
p2->next = p3->next; //把链表跳过p3
free(p3); //释放内存
}
else
{
p2 = p2->next; //遍历后面的节点
}
}
p1 = p1->next; //外循环移动节点向后
p2 = p1;
}
}

int search_lklist(linklist_t *plklist, int val)
{
int i = 1;
node_t *p = plklist->head;

while(p != NULL && p->data != val)
{
p = p->next;
i++;
}
if(i > plklist->length)
{
printf("can not find anything !\n");
exit(-1);
}

printf("the position is %d\n",i);
return 0;
}

int length_list(linklist_t *plklist)
{
node_t *p = plklist->head;
int count = 0;

while(p != NULL)
{
p = p->next;
count++;
}
return count;
}


int sort_list(linklist_t *plklist)
{

node_t *p;
node_t *q;
int temp;

for(p = plklist->head; p !=NULL; p=p->next)
{
for(q = p->next; q!=NULL; q = q->next)
{
if(p->data > q->data)
{
temp = p->data;
p->data = q->data;
q->data = temp;
}
}
}
}

int sort_list2(linklist_t *plklist)
{
linklist_t sortlist;
linklist_t *slist= init_lklist(&sortlist);//定义一个新的链表,用来存放排序好的

node_t *pnew = NULL;

printf("here1\n");
while(1)
{printf("here2\n");
pnew = plklist->head; //定义一个中间节点,取出1 的头结点

if(pnew == NULL) //当pnew 指向空的时候,说明1 已经取完了,跳出循环
break;

plklist->head = plklist->head->next; //把头结点向后移动,不能移动pnew节点,会死循环
pnew->next = NULL; //把pnew 从1 中断出来

if(slist->head == NULL) // 1,当2 为空的时候就直接就直接插在第一个
{
slist->head = pnew;
slist->tail = pnew;
slist->length++;
}
else // 2, 2不为空的情况
{
if(pnew->data <= slist->head->data) // 1 。2不为空,pnew小于等于2 的头结点的时候直接头插
{
head_inser_lklist(slist, pnew);
}
else if(pnew->data > slist->tail->data) // 2 。2不为空,pnew大于2 的尾节点的时候直接尾插
{
tail_inser_lklist(slist, pnew);
}
else //中间插入的情况
{

node_t *pcur = NULL;
node_t *pre = NULL;

pcur = slist->head->next;
pre = slist->head; //定义两个节点,指向前驱和后驱

while(pcur != NULL) //必须加循环
{
if(pnew->data <= pcur->data) //因为2 已经是有序的了,只要满足这个就可以直接插入了
{
pnew->next = pcur;
pre->next = pnew;
slist->length++;
break; //插入完成后,跳出循环,在1 中再取一个元素
}
else //移动前驱和后驱
{
pre = pcur;
pcur = pcur->next;
}
}
}
}
}
plklist->head = slist->head;//把有序的新链表赋给原来的链表,返回结果
plklist->tail = slist->tail;
plklist->length = slist->length;
}
int create_list(linklist_t *plklist)
{
int num;
node_t *pnode;

printf("input the number to create a linklist end with '0' :\n");
scanf("%d",&num);

while(num != 0)
{
pnode=(node_t*)malloc(sizeof(node_t));
pnode->data = num;
pnode->next = NULL;

tail_inser_lklist(plklist, pnode);
scanf("%d",&num);
}
}


int show_llist(linklist_t *plklist)
{
node_t *pcur = plklist->head;
printf("hellos%d\n",plklist->length);

while(pcur != NULL)
{
printf("%d\n",pcur->data);
pcur = pcur->next;
}
}


int main(int argc, char* argv[])
{
int num;
int pos;
int count;
int delpos;
int searval;

linklist_t lklist;
linklist_t *list;
list = init_lklist(&lklist); //鍒濆鍖栧畬閾捐〃锛屽緱鍒伴摼琛ㄦ寚閽?

create_list(list); //鍒涘缓閾捐〃骞朵笖鏄剧ず
show_llist(list);

count = length_list(list); //鑾峰緱閾捐〃鐨勯暱搴﹀苟涓旀樉绀?
printf("length = %d\n",count);
/*
printf("insert the position and number :"); //瀵瑰簲浣嶇疆鎻掑叆鏁板€硷紝骞舵樉绀烘彃鍏ュ悗鐨勯摼琛?
scanf("%d,%d",&pos,&num);
middle_inser_lklist(list, pos, num);
show_llist(list);

printf("delete the position :"); //瀵瑰簲浣嶇疆鍒犻櫎鏁板€硷紝骞舵樉绀哄垹闄ゅ悗鐨勯摼琛?
scanf("%d",&delpos);
delete_lklist(list, delpos);
show_llist(list);

printf("search the number :"); //瀵瑰簲浣嶇疆鍒犻櫎鏁板€硷紝骞舵樉绀哄垹闄ゅ悗鐨勯摼琛?
scanf("%d",&searval);
search_lklist(list, searval);

// sort_list(list);
//show_llist(list);

sort_list2(list);
show_llist(list);
*/

delete_same(list);
show_llist(list);
return 0;
}

 

 

这些都是简单的小功能,需要的时候还要继续加深巩固。代码风格和规范都有待加强啊,多写写注释,还要好好设计形式参数和返回值,这些都要养成良好的习惯。

  不多数说了,现在的任务是用链表实现成绩管理系统(向着2000+选课系统又迈近一小步。。。)