zoukankan      html  css  js  c++  java
  • Chapter 3(线性表)



    1.单链表
    //单链表代码,手打纯手工
    
    
    //***********************************link.h***********************************
    #ifndef LINK_H
    #define LINK_H
    
    
    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    
    typedef int datatype;
    
    typedef struct link
    {
    	datatype data;
    	struct link *next;
    
    
    }Node,*Link;
    
    
    //创建单链表
    Link linkCreate();
    
    
    //获得链表长度
    size_t length(Link link);
    
    //判断链表是否为空
    bool isEmpty(Link link);
    
    //获得第i个前的地址
    Node *addressFront(Link link,size_t i);
    
    //获取第i个节点的值
    datatype getElement(Link link,size_t i);
    
    
    //查找元素num是否存在
    bool isExist(Link link,datatype num);
    
    //插入元素
    bool insert(Link link,size_t i,datatype num);
    
    //在链表头插入元素
    bool pushFront(Link link,datatype num);
    
    //在链表尾插入元素
    bool pushBack(Link link,datatype num);
    
    //删除第i个元素
    bool deleteI(Link link,size_t i);
    
    
    //删除包含元素num的第一个节点
    bool deleteNum(Link link,datatype num);
    
    //遍历打印整个链表
    void travel(Link link);
    
    //清空链表
    bool clear(Link link);
    
    //销毁链表
    bool destroy(Link link);
    
    //链表翻转
    bool reverse(Link link);
    
    //链表指定长度反转
    void reverseN(Link link,int n);
    
    
    
    
    #endif //LINK_H
    
    
    
    //*************************link.c****************************************
    #include "link.h"
    
    
    
    
    //创建单链表头
    Link linkCreate()
    {
    	Node *p = (Node *)malloc(sizeof(Node));
    	p->next = NULL;
    	return p;
    }
    
    
    //获得链表长度
    size_t length(Link link)
    {
    	size_t count = 0;
    	Node *node = link->next;
    	while(node)
    	{
    		count++;
    		node = node->next;
    	}
    	return count;
    }
    
    //判断链表是否为空
    bool isEmpty(Link link)
    {
    	if(NULL == link->next)return true;
    	return false;
    }
    
    
    //获得第i个前的地址,供内部使用
    Node *addressFront(Link link,size_t i)
    {
    	if(NULL == link)return NULL;//头节点为空,返回NULL
    	
    	if(i > (length(link)+1))return NULL;//i越界,len+1是可取的,相当于最后加上这个数,i不能为0.返回于NULL
    
    	if(isEmpty(link))return link;//当链表为空时,返回头节点地址
    
    	Node *pre  = link; //保存前一个节点的地址
    	Node *curr = link->next;
    	for(size_t j = 1;j < i;j++)
    	{
    		pre  = curr;
    		curr = curr->next; 
    	}
    
    	return pre;
    }
    
    //获取第i个节点的值
    datatype getElement(Link link,size_t i)
    {
    	Node *node = addressFront(link,i);
    	return node->next->data;
    }
    
    
    //查找元素num是否存在
    bool isExist(Link link,datatype num)
    {
    	if(NULL == link)return false;
    
    	Node *node = link->next;
    	
    	while(node)
    	{
    		if(num == node->data)return true;
    		node = node->next;
    	}
    	return false;
    }
    
    //插入元素
    bool insert(Link link,size_t i,datatype num)
    {
    	if(NULL == link)return false;
    	if(i > (length(link)+1)||i <= 0)return false;
    
    
    	Node *pre  = addressFront(link,i);//获得第i-1个节点的地址
    	Node *node = (Node *)malloc(sizeof(Node));//申请内存存放新节点
    	Node *save = pre->next; //将原来的第i个节点的地址保存在save中
    	
    	pre->next = node; //将原来的第i-1个节点指向新节点
    
    	node->data = num; //为新节点的数据域赋值
    	node->next = save;//将新节点指向原来的第i个节点
    	
    	return true;
    }
    
    //在链表头插入元素
    bool pushFront(Link link,datatype num)
    {
    	return insert(link,1,num);
    }
    
    //在链表尾插入元素
    bool pushBack(Link link,datatype num)
    {
    	return insert(link,length(link)+1,num);
    }
    
    //删除第i个元素
    bool deleteI(Link link,size_t i)
    {
    	if(NULL == link)return false;
    	if(i>length(link) || i<=0)return false;
    
    
    	Node *pre = addressFront(link,i);
    	Node *node= pre->next;
    
    	pre->next = node->next;
    	free(node);
    	node = NULL;
    	return true;
    }
    
    
    //删除包含元素num的第一个节点
    bool deleteNum(Link link,datatype num)
    {
    	if(NULL == link)return false;
    	
    	Node *pre  = link;
    	Node *curr = link->next;
    	while(curr)
    	{
    		if(num == curr->data)
    		{
    			pre->next = curr->next;
    			free(curr);
    			curr = NULL;
    			return true;
    		}
    		pre = curr;
    		curr= curr->next;
    	}
    
    	return false;
    }
    
    //遍历打印整个链表
    void travel(Link link)
    {
    	if(NULL == link)return;
    
    	Node *node = link->next;
    	while(node)
    	{
    		printf("%d ",node->data);
    		node = node->next;
    	}
    	printf("
    ");
    }
    
    //清空链表
    bool clear(Link link)
    {
    	if(NULL == link)return false;
    
    	Node *node = link->next;//从头节点开始释放
    	
    	while(node)
    	{
    		Node *temp = node->next;//保存下一个节点的地址
    		free(node);//释放当前节点
    		node = temp;//将下一个节点地址赋给node
    	}
    	link->next = NULL;//头节点指向空
    
    	return true;
    }
    
    //销毁链表
    bool destroy(Link link)
    {
    	if(NULL == link)return false;
    
    	clear(link);
    	free(link);
    	link = NULL;
    	return true;
    }
    
    
    //链表翻转
    bool reverse(Link link)
    {
    	if(NULL == link)return false;
    
    	Node *pre = link->next;
    	Node *curr= pre->next;
    
    	while(curr)
    	{
    		Node *temp = curr->next;//保存当前节点的下一个节点地址
    		curr->next = pre;//将当前节点指向上一个节点
    
    		pre = curr;//将上一个节点指向当前节点
    		curr= temp;//将当前节点指向喜爱一个节点
    	}
    	
    	link->next->next = NULL;//将原来第一个节点指向空
    	link->next = pre;//将头节点指向原来的最后一个节点
    	return true;
    }
    
    
    //链表指定长度反转工具
    void reverseTool(Node *prev,Node *curr,int num)
    {
    	if(NULL == curr)return;
    
    	Node *prevNode = curr;
    	Node *currNode = curr->next;
    
    	int count = 1;
    	while(currNode)
    	{
    		Node *nextNode = currNode->next;
    		currNode->next = prevNode;
    		prevNode = currNode;
    		currNode = nextNode;
    		count++;
    
    		if(num == count)
    		{
    			Node *temp = prev->next;
    			prev->next->next =currNode;
    			prev->next = prevNode;
    			reverseTool(temp,currNode,num);
    			return;
    		}
    	}
    
    	prev->next->next = currNode;
    	prev->next = prevNode;
    }
    
    //链表指定长度反转
    void reverseN(Link link,int n)
    {	
    	Node *node = link->next;
    	reverseTool(link,node,n);
    }
    
    
    
    //************************linkTest.c*****************************************
    
    
    #include "link.h"
    
    int main(int argc,char *argv[])
    {
    	Link head = linkCreate();
    	travel(head);
    	insert(head,1,77);
    	travel(head);
    	insert(head,1,777);
    	travel(head);
    	insert(head,3,7777);
    	travel(head);
    	printf("length = %d
    ",length(head));
    
    	pushFront(head,52);
    	travel(head);
    	printf("length = %d
    ",length(head));
    
    
    	pushBack(head,00);
    	travel(head);
    	printf("length = %d
    ",length(head));
    
    	//deleteNum(head,777);
    	//deleteI(head,2);
    	travel(head);
    	printf("length = %d
    ",length(head));
    	
    
    	printf("-----
    ");
    	reverseN(head,2);
    	//clear(head);
    	travel(head);
    	return 0;
    }

    2.静态链表
    //静态链表代码,纯手打
    
    //********************static_link.h***********************
    #ifndef STATIC_LINK_H
    #define STATIC_LINK_H
    
    #include <stdio.h>
    #include <stdbool.h>
    #define MAXSIZE 1000
    
    typedef int datatype;
    
    
    typedef struct Static_linklist
    {
    	datatype data;
    	int curr;
    }Node,static_link[MAXSIZE];
    
    
    //初始化静态链表
    bool InitList(static_link link);
    
    
    
    //获取链表长度
    size_t length(static_link link);
    
    //Malloc_SLL若备用链表非空,则返回分配的节点下标,否则返回0
    int Malloc_SLL(static_link link);
    
    //Free_SSL将下标为K的空闲节点回收到备用链表
    void Free_SSL(static_link link,int k);
    
    //插入元素
    bool insert(static_link link,int i,datatype num);
    
    //删除元素
    bool Delete(static_link link,int i );
    
    //判断链表是否为空
    bool isEmpty(static_link link);
    
    //获取第i个对象的值
    datatype getElement(static_link link,int i);
    
    
    //历遍整个链表
    void travel(static_link link);
    
    #endif //STATIC_LINK_H
    
    
    
    //********************static_link.c***********************
    #include "static_link.h"
    
    
    //初始化静态链表
    bool InitList(static_link link)
    {
    	if(NULL == link)return false;
    	for(int i = 0;i < MAXSIZE-1;i++)
    	{
    		link[i].curr = i+1;
    	}
    	link[MAXSIZE-1].curr = 0;
    	return true;
    }
    
    
    
    //获取链表长度
    size_t length(static_link link)
    {
    	if(NULL == link)return false;
    
    	size_t index = link[MAXSIZE-1].curr;
    	size_t count = 0;
    	
    	while(index)
    	{
    		count++;
    		index = link[index].curr;
    	}
    
    	return count;
    }
    
    //Malloc_SLL若备用链表非空,则返回分配的节点下标,否则返回0
    int Malloc_SLL(static_link link)
    {
    	if(0 == link[0].curr)return 0;
    
    	int result = link[0].curr;
    	link[0].curr = link[link[0].curr].curr;
    	return result;
    }
    
    //Free_SSL将下标为K的空闲节点回收到备用链表
    void Free_SSL(static_link link,int k)
    {
    	link[k].curr = link[0].curr;
    	link[0].curr = k;
    }
    
    //插入元素
    bool insert(static_link link,int i,datatype num)
    {
    	if(i<1 || i > length(link)+1)return false; //当输入的i小于1或者比链表长度+1大,则非法。
    	int index = Malloc_SLL(link);
    
    	if(index)
    	{
    		link[index].data = num;
    		
    		int index_front = MAXSIZE-1;
    		for(int j = 1;j < i;j++)
    		{
    			index_front = link[index_front].curr;
    		}
    		link[index].curr = link[index_front].curr;
    		link[index_front].curr = index;
    		return true;
    	}
    	return false;
    }
    
    //删除元素
    bool Delete(static_link link,int i )
    {
    	if(i<1 || i > length(link))return false;
    	size_t index = MAXSIZE-1;
    	for(int j =1;j < i;j++)
    	{
    		index = link[index].curr;
    	}
    	size_t tmp = link[index].curr;
    	link[index].curr = link[tmp].curr;
    	Free_SSL(link,i);
    	return true;
    }
    
    //判断链表是否为空
    bool isEmpty(static_link link)
    {
    	return !link[MAXSIZE-1].curr;
    }
    
    //获取第i个对象的值
    datatype getElement(static_link link,int i)
    {
    	if(i<1 || i>length(link))return ~(1<<(sizeof(datatype)*8-1))+1;//这里由于函数的返回值是数据类型,因此不能返回false来报告输入错误,因此后面取了这个数据类型的最大值+1输出表示输入下标不合法
    
    	size_t index = link[MAXSIZE-1].curr;
    	for(size_t j = 1;j < i;j++)
    	{
    		index = link[index].curr;
    	}
    	return link[index].data;
    }
    
    //历遍整个链表
    void travel(static_link link)
    {
    	size_t index = link[MAXSIZE-1].curr;
    	while(index)
    	{
    		printf("%d ",link[index].data);
    		index = link[index].curr;
    	}
    	printf("
    ");
    }
    
    
    
    //********************static_linkTest.c***********************
    #include "static_link.h"
    
    
    
    
    
    int main()
    
    {
    
    	Node arr[MAXSIZE];
    
    	InitList(arr);
    
    	
    
    	printf("isEmpty: %d 
    ",isEmpty(arr));
    
    
    
    	travel(arr);
    
    	insert(arr,1,77);
    
    	insert(arr,2,25);
    
    	printf("isEmpty: %d 
    ",isEmpty(arr));
    
    	travel(arr);
    
    	//Delete(arr,2);
    
    	//travel(arr);
    
    	//printf("isEmpty: %d 
    ",isEmpty(arr));
    
    	printf("arr[2]:%d 
    ",getElement(arr,2));
    
    	printf("arr[3]:%d 
    ",getElement(arr,3));
    
    	return 0;
    
    }


    3.循环链表
    //******************************circular_link.h**************************************
    #ifndef CIRCULAR_LINK_H
    #define CIRCULAR_LINK_H
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    typedef int datatype;
    
    typedef struct circular_link
    {
    	datatype data;
    	struct circular_link *next;
    }Node,*Link;
    
    
    //创建链表
    Link create();
    
    //获取链表长度
    size_t length(Link link);
    
    //获取第i-1个节点的地址,工具函数内部使用
    Node *addressTool(Link link,size_t i);
    
    
    //插入节点
    bool insert(Link link,size_t i,datatype data);
    
    //删除节点
    bool Delete(Link link,size_t i);
    
    //历遍节点
    void travel(Link link);
    
    //判断节点是否为空
    bool isEmpty(Link link);
    
    //获取第i个节点的数据
    datatype getElement(Link link,size_t i);
    
    
    
    
    #endif //CIRCULAR_LINK_H
    
    
    //******************************circular_link.c**************************************
    #include "circular_link.h"
    
    
    
    //创建链表 创建失败返回NULL
    Link create()
    {
    	Link link = (Link)malloc(sizeof(Node));
    	link->next = link;
    	return link;
    }
    
    //获取链表长度
    size_t length(Link link)
    {
    	if(NULL==link || NULL==link->next)return false;
    
    
    	Node *node = link->next;
    	int count = 0;
    	while(node != link)
    	{
    		count++;
    		node = node->next;
    	}
    
    	return count;
    }
    
    //获取第i-1个节点的地址,工具函数内部使用
    Node *addressTool(Link link,size_t i)
    {
    	Node *node = link;
    	for(size_t j = 1;j < i;j++)
    	{
    		node = node->next;
    	}
    	return node;
    }
    
    
    //插入节点
    bool insert(Link link,size_t i,datatype data)
    {	
    	if(i<1 || i > length(link)+1)return false;
    	if(NULL == link)return false;
    
    	Node *prev = addressTool(link,i);//获取第i-1个节点地址
    	Node *curr = prev->next;//获取第i个节点地址
    	
    	Node *node = (Node *)malloc(sizeof(Node));//创建新节点	
    	node->data = data;
    
    	prev->next = node;
    	node->next = curr;
    
    	return true;
    }
    
    //删除节点
    bool Delete(Link link,size_t i)
    {
    	if(i<1 || i>length(link))return false;
    	if(NULL == link)return false;
    
    	Node *prev = addressTool(link,i);
    	Node *curr = prev->next;
    	Node *temp = curr->next;
    
    	prev->next = temp;
    	free(curr);
    	curr = NULL;
    	return true;
    }
    
    //历遍节点
    void travel(Link link)
    {
    	Node *node = link->next;
    	while(node != link)
    	{
    		printf("%d ",node->data);
    		node = node->next;
    	}
    	printf("
    ");
    }
    
    //判断节点是否为空
    bool isEmpty(Link link)
    {
    	return link->next == link;
    }
    
    //获取第i个节点的数据
    datatype getElement(Link link,size_t i)
    {
    	if(i<1 || i > length(link) || NULL == link)return !(1<<(sizeof(datatype)-1))+1;
    
    	Node *node = link->next;
    
    	for(size_t j = 1;j < i;j++)
    	{
    		node = node->next;
    	}
    	return node->data;
    }
    
    
    //******************************circular_linkTest.c**************************************
    
    #include "circular_link.h"
    
    
    
    
    
    int main()
    
    {
    
    	Link head = create();
    
    	printf("isEmpty: %d 
    ",isEmpty(head));
    
    	printf("%d 
    ",length(head));
    
    	travel(head);
    
    
    
    	insert(head,1,77);
    
    	travel(head);
    
    	printf("isEmpty: %d 
    ",isEmpty(head));
    
    	insert(head,1,52);
    
    	insert(head,1,44);
    
    	travel(head);
    
    	printf("%d 
    ",length(head));
    
    
    
    	printf("head:1:%d 
    ",getElement(head,1));
    
    	printf("head:2:%d 
    ",getElement(head,2));
    
    	printf("head:3:%d 
    ",getElement(head,3));
    
    	
    
    //	Delete(head,1);
    
    //	travel(head);
    
    //	Delete(head,1);
    
    //	travel(head);
    
    //	Delete(head,1);
    
    //	travel(head);
    
    	return 0;
    
    }

    4.双向循环链表
    //**********************************double_link.h************************************
    #ifndef DOUBLE_LINK_H
    #define DOUBLE_LINK_H
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    typedef int datatype;
    
    typedef struct double_link
    {
    	datatype data;
    	struct double_link *prior;
    	struct double_link *next;
    }DulNode,*DulLink;
    
    
    //创建链表
    DulLink create();
    
    //链表长度
    size_t length(DulLink link);
    
    //链表是否为空
    bool isEmpty(DulLink link);
    
    //获取第i-1和节点的地址,工具函数,内部使用
    DulNode *addressTool(DulLink link,size_t i);
    
    //插入节点
    bool insert(DulLink link,size_t i,datatype data);
    
    //删除节点
    bool Delete(DulLink link,size_t i);
    
    //历遍节点
    void travel(DulLink link);
    
    
    #endif //DOUBLE_LINK_H
    
    
    
    
    
    //**********************************double_link.c************************************
    #include "double_link.h"
    
    
    //创建双向循环链表
    DulLink create()
    {
    	DulLink link = (DulLink)malloc(sizeof(DulNode));
    	link->prior = link;
    	link->next  = link;
    	return link;
    }
    
    //链表长度
    size_t length(DulLink link)
    {
    	if(NULL == link)return 0;
    
    	DulNode *node = link->next;
    	size_t count = 0;
    	while(node != link)
    	{
    		count++;
    		node = node->next;
    	}
    
    	return count;
    }
    
    //链表是否为空
    bool isEmpty(DulLink link)
    {
    	return (link->next == link);
    }
    
    //获取第i-1和节点的地址,工具函数,内部使用
    DulNode *addressTool(DulLink link,size_t i)
    {	
    	DulNode *prev = link;
    	for(int j = 1;j < i;j++)
    	{
    		prev = prev->next;
    	}
    	return prev;
    }
    
    //插入节点
    bool insert(DulLink link,size_t i,datatype data)
    {
    	if(i<1 || i > length(link)+1)return false;
    	if(NULL == link)return false;
    
    	DulNode *prev = addressTool(link,i);//获得第i-1个节点的地址
    	DulNode *old  = prev->next;//获得原来第i个地址
    
    	DulNode *node = (DulNode *)malloc(sizeof(DulNode));//创建新节点
    	node->data = data;
    
    	prev->next = node;  //新节点与prev节点的连接
    	node->prior= prev;
    
    	node->next = old;
    	old->prior = node;
    
    	return true;
    }
    
    //删除节点
    bool Delete(DulLink link,size_t i)
    {
    	if(i<1 || i>length(link))return false;
    	if(NULL == link)return false;
    
    	DulNode *prev = addressTool(link,i);//获取第i-1个节点地址
    	DulNode *curr = prev->next;
    	DulNode *behind = curr->next;
    
    	prev->next = behind;//将第i-1个节点和i+1个节点连接起来
    	behind->prior = prev;
    
    	free(curr);//释放第i个节点
    	curr = NULL;
    
    	return true;
    }
    
    //历遍节点
    void travel(DulLink link)
    {
    	DulNode *node = link->next;
    	while(node != link)
    	{
    		printf("%d ",node->data);
    		node = node->next;
    	}
    	printf("
    ");
    }
    
    
    
    //**********************************double_linkTest.c************************************
    #include "double_link.h"
    
    
    int main()
    {
    	DulLink head = create();
    	printf("length: %d 
    ",length(head));
    	printf("isEmpty: %d 
    ",isEmpty(head));
    
    	insert(head,1,77);
    	travel(head);
    	insert(head,1,52);
    	travel(head);
    	insert(head,3,1314);
    	travel(head);
    	
    	insert(head,1,74);
    	insert(head,1,75);
    	travel(head);
    	Delete(head,2);
    	travel(head);
    	Delete(head,1);
    	travel(head);
    	return 0;
    }

    附件列表

  • 相关阅读:
    UpdatePanel 脚本失效的解决
    DataTable 中的查询、排序及分页(c#)
    如何让Gridview在没有数据的时候显示表头
    Jquery 对.net服务器控件RadioButtonList进行赋值和取值的操作
    给Repeater控件里添加序号的5种方法
    C#缓存absoluteExpiration、slidingExpiration两个参数的疑惑
    筛选DataTable数据的方法
    CSS前端基础应用实践
    js实现页面自动刷新
    什么是MVC
  • 原文地址:https://www.cnblogs.com/LyndonMario/p/9326332.html
Copyright © 2011-2022 走看看