C语言实现单链表

/*
 * link_list.h
 *
 *  Created on: 2011-9-2
 *      Author: liusheng
 */

#ifndef LINK_LIST_H_
#define LINK_LIST_H_

#define ElemType int
#define FALSE 0;
#define TRUE 1;
typedef struct list_node {
	ElemType date;
    struct list_node *next;
}node,*linklist;

//初始化单链表
int initlinklist(linklist *l) {
    (*l) = (node *)malloc(sizeof(node));
    if(*l == NULL) return FALSE;
    (*l)->next = NULL;
    (*l)->date = 0;
    return TRUE;
}
/*linklist initlinklist() {
	node *l = NULL;
	l = (node *)malloc(sizeof(node));
	if(l == NULL) return l;
	l->date = 0;//将链表的长度设为0
	l->next = NULL;
	printf("%d\n",l);
	return l;
}*/
//用头插发建立单链表
int addnodehead(linklist l,ElemType e) {
	node *s;
	s = (node *)malloc(sizeof(node));
	if(s == NULL) return FALSE;
	s->next = l->next;
	l->next = s;
	s->date = e;
	l->date ++;
	return TRUE;
}
//用尾插法建立单链表
int addnodetail(linklist l,ElemType e) {
	node *s,*addnode;
	s = l;
	while(s->next != NULL) {
		s = s->next;
	}
	addnode = (node *)malloc(sizeof(node));
	if(addnode == NULL) return FALSE;
	s->next = addnode;//将新的节点的地址给s
	addnode->date = e;
	addnode->next = NULL;
	l->date ++;
	return TRUE;
}
//在链表的第i个数据前插入数据
int insertlinklistnode(linklist l,int i,ElemType e) {
	if(i<1 || i>l->date) return FALSE;
	node *s,*addnode;
	s = l;
	while(i > 1) {
		s = s->next;
		i --;
	}
	addnode = (node *)malloc(sizeof(node));
	addnode->next = s->next;
	s->next = addnode;
	addnode->date = e;
	l->date ++;
	return TRUE;
}
//删除链表指定的第i个数据
int deletelinklistnode(linklist l,int i,ElemType *e) {
	if(i<1 || i>l->date) return FALSE;
	node *s;
	s = l;
	while(i > 1) {
		s = s->next;
		i --;
	}
	node *temp;
	temp = s->next;
	(*e) = temp->date;
	s->next = s->next->next;
	free(temp);
	l->date --;
	return TRUE
}
//删除单链表中指定了值的数据
int deleteelem(linklist l,ElemType e) {
	node *s;
	s = l;
	int count = 0;//记录一空删除了几个值
	int temp = 0;//遍历元素的个数
	while(s->next != NULL) {
		s = s->next;
		temp ++;
		if(s->date == e) {
			count ++;
			deletelinklistnode(l,temp,&e);
		    temp --;
		}
	}
	return count;
}
//若Elemtype为int将链表中的数据从小到大排序
void sortlinklist(linklist l) {
    node *first,*final;
    final = l;
    while(final->next != NULL) {
    	final = final->next;
    }
    first = l->next;
    int temp = 0;
    while(final != l->next) {
    	while(first != final) {
    		if(first->date > first->next->date) {
    			temp = first->date;
    			first->date = first->next->date;
    			first->next->date = temp;
    		}
    		temp = (int)first;//记录final前一个节点的地址
    		first = first->next;
    	}
    	first = l->next;
    	final = (node *)temp;
    }
}
/*
 * 将两张有序单链表合并一张有序单链表,不用前面的sortlinklist方法
 * 当然单张的有序单链表要使用sortlinklist排序
 */

linklist combinelinklist(linklist la,linklist lb) {
	linklist lc;
	node *pa,*pb,*pc;
	lc = la;
	pa = la->next;
	pb = lb->next;
	pc = lc;
	while(pa != NULL && pb != NULL) {
		if(pa->date < pb->date) {
			pc->next = pa;//这段代码是关键
			pc = pa;
			pa = pa->next;
		} else {
			pc->next = pb;
            pc = pb;
			pb = pb->next;
		}
	}
	pc->next = pa?pa:pb;
	return lc;
}

//输出单链表中的所有元素
void printfnode(linklist l) {
	node *s;
	s = l->next;//存储第一个节点的地址
	while(s!= NULL) {
		printf(" date = %d",s->date);
	    s = s->next;//与上面一行有什么区别
	}
}
#endif /* LINK_LIST_H_ */

/*
 * linklist.c
 * 对link_list.h测试
 *  Created on: 2011-9-2
 *      Author: liusheng
 */
#include <stdio.h>
#include <stdlib.h>
#include "link_list.h"
int main(void) {
    linklist l = NULL;//第一个节点
    //l = initlinklist();//将链表初始化l->next = NULL;
    initlinklist(&l);
    addnodehead(l,10);
    addnodehead(l,20);
    addnodehead(l,30);
    addnodehead(l,40);
    addnodetail(l,5);
    addnodetail(l,6);
    addnodetail(l,6);
    printfnode(l);
    printf("\n");
    printf("%d\n",l->date);
    //测试插入节点
    insertlinklistnode(l,2,8);
    printfnode(l);
    printf("\n");
    printf("%d\n",l->date);

    //测试删除指定节点
    ElemType e;
    deletelinklistnode(l,3,&e);
    deletelinklistnode(l,3,&e);
    deletelinklistnode(l,3,&e);
    printfnode(l);
    printf("\n");
    printf("%d\n",l->date);
    printf("%d\n",e);
    deleteelem(l,6);
    printfnode(l);
    printf("\n");
    printf("%d\n",l->date);
    //测试将链表排序
    sortlinklist(l);
	printfnode(l);
	printf("\n");
	printf("%d\n",l->date);

	//测试将两个顺序链表合并成一个链表
	linklist lb,lc;
    initlinklist(&lb);
	initlinklist(&lc);
	addnodehead(lb,100);
	addnodehead(lb,8);
	addnodehead(lb,16);
	addnodehead(lb,4);
	addnodehead(lb,99);
	sortlinklist(lb);
	printfnode(lb);
	printf("\n");
	lc = combinelinklist(l,lb);
	printfnode(lc);
	return 0;
}

以下是测试后的结果

 date = 40 date = 30 date = 20 date = 10 date = 5 date = 6 date = 6
7
 date = 40 date = 8 date = 30 date = 20 date = 10 date = 5 date = 6 date = 6
8
 date = 40 date = 8 date = 5 date = 6 date = 6
5
10
 date = 40 date = 8 date = 5
3
 date = 5 date = 8 date = 40
3
 date = 4 date = 8 date = 16 date = 99 date = 100
 date = 4 date = 5 date = 8 date = 8 date = 16 date = 40 date = 99 date = 100







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值