线性表详述

1. 线性表:n个数据元素的有序集合。

线性表是一种常用的数据结构在实际应用中,线性表都是以、队列、字符串数组等特殊线性表的形式来使用的。由于这些特殊线性表都具有各自的特性,因此,掌握这些特殊线性表的特性,对于数据运算的可靠性和提高操作效率都是至关重要的。  线性表是一个线性结构,它是一个含有n≥0个结点的有限序列,对于其中的结点,有且仅有一个开始结点没有前驱但有一个后继结点,有且仅有一个终端结点没有后继但有一个前驱结点,其它的结点都有且仅有一个前驱和一个后继结点。

特征:

1.集合中必存在唯一的一个“第一元素”;
2.集合中必存在唯一的一个 “最后元素” ;
3.除最后一个元素之外,均有 唯一的后继(后件);
4.除第一个元素之外,均有 唯一的前驱(前件)。

java中的List接口,就是线性表。ArrayList就是顺序线性表,LinkedList就是链表线性表。

2. 线性表的顺序表示:ArrayList

一般使用数组(C语言中的数组采用顺序存储方式。即连续地址存储)来描述。

优点:在于随机访问元素,

缺点:插入和和删除的时候,需要移动大量的元素。

c语言实现代码:

  1. // Test.cpp : Defines the entry point for the console application.  
  2. //  
  3.  
  4. #include "stdafx.h"  
  5. #include <stdio.h>  
  6. #include "stdlib.h"  
  7. //宏定义  
  8. #define TRUE   1  
  9. #define FALSE   0  
  10. #define OK    1  
  11. #define ERROR   0  
  12. #define INFEASIBLE -1  
  13. #define OVERFLOW -2  
  14.  
  15. #define LT(a,b)   ((a)<(b))  
  16. #define N = 100         
  17.  
  18. #define LIST_INIT_SIZE 100 //线性表初始空间分配量  
  19. #define LISTINCREMENT   10 //线性表空间分配的增量  
  20.  
  21. typedef int Status; 
  22. typedef int ElemType; 
  23.  
  24. typedef struct LNode{ 
  25.     ElemType  *elem;        //存储空间的基地址  
  26.     int      lenght;        //当前的长度  
  27.     int      listsize;      //当前分配的存储容量  
  28. }SqList; 
  29.  
  30. /**
  31. *构造空的线性表
  32. */ 
  33.  
  34. Status initList(SqList &L, int lenght){ 
  35.     if (lenght == 0) lenght = LIST_INIT_SIZE; 
  36.     L.elem = (ElemType *)malloc(lenght * sizeof(ElemType)); 
  37.     if(!L.elem) exit(OVERFLOW);  //分配存储空间失败  
  38.     L.lenght = 0;                //初始空表长度为0  
  39.     L.listsize = lenght ;//初始存储容量为100  
  40.     return OK; 
  41. /************************************************************************/ 
  42. /* 在第i位置插入e
  43. */ 
  44. /************************************************************************/ 
  45. Status insertList(SqList &L, ElemType e, int i){ 
  46.     ElemType *p,  *q; 
  47.     if(i<0 ||i > L.lenght) return ERROR;  //i值不合法  
  48.     if (L.lenght >= L.listsize) { 
  49.         ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType)); 
  50.         if(!newbase) return OVERFLOW;   //存储分配失败    
  51.         L.elem = newbase;               //新基值  
  52.         L.listsize += LISTINCREMENT;    //增加存储容量  
  53.     } 
  54.     q = &L.elem[i];                     //q为插入的位置  
  55.     for (p = &L.elem[L.lenght]; p>=q; --p) { 
  56.         *p = *(p-1);                    //i元素之后的元素往后移动  
  57.     } 
  58.     *q = e;                             //插入e  
  59.     L.lenght +=1; 
  60.     return OK; 
  61.  
  62. /************************************************************************/ 
  63. /* 快速排序
  64. */ 
  65. /************************************************************************/ 
  66. void sortList(SqList &L){ 
  67.      
  68.  
  69. /************************************************************************/ 
  70. /* 删除第i位置元素,并用e返回其值                                                                     */ 
  71. /************************************************************************/ 
  72. Status deleteListElem(SqList &L, int i, ElemType &e){ 
  73.     int *p,  *q; 
  74.     if(i<0 ||i > L.lenght) return ERROR;  //i值不合法  
  75.     q = &L.elem[i];                       //被删除元素的位置为i,L.elem就是数组名,  
  76.     e = *q;                               //被删除元素的值赋值给e  
  77.     for (p = q; p< (L.elem + L.lenght); p++){ //元素左移  
  78.         *p = *(p+1); 
  79.     } 
  80.     --L.lenght; 
  81.     return OK; 
  82.  
  83. /************************************************************************/ 
  84. /*  快速排序
  85. */ 
  86. /************************************************************************/ 
  87.  
  88. int partition(SqList &L, ElemType low, ElemType high){ 
  89.     ElemType pivotkey = L.elem[low];               //枢轴记录关键字  
  90.     while (low < high) {                  //从表的两端向中间扫描  
  91.         while (low < high &&  L.elem[high] >= pivotkey ) --high;//高端位置扫描  
  92.         L.elem[low] = L.elem[high];     //交换数据,小于pivotkey移到低端  
  93.         L.elem[high] = pivotkey; 
  94.  
  95.         while (low < high && L.elem[low] <= pivotkey ) ++low;     //低端扫描  
  96.         L.elem[high] = L.elem[low];               //交换数据 大于pivotkey移到高端  
  97.         L.elem[low] = pivotkey;                                  
  98.     } 
  99.     return low; 
  100.  
  101. void quickSort(SqList &L, ElemType low, ElemType high){ 
  102.     int pivot; 
  103.     if(low < high) {                                         
  104.         pivot =  partition(L,  low,  high);      
  105.         quickSort(L,  low,  pivot -1);          //低端子表排序  
  106.         quickSort(L,  pivot +1, high);          //高端子表排序  
  107.     } 
  108.      
  109.  
  110.  
  111. /************************************************************************/ 
  112. /*
  113. 合并两个线性表
  114. */ 
  115. /************************************************************************/ 
  116.  
  117. void mergeList(SqList La, SqList Lb,  SqList &Lc){ 
  118.     ElemType *pa, *pb, *pc; 
  119.     Lc.listsize =  La.lenght + Lb.lenght; 
  120.     initList(Lc, Lc.listsize);          //初始化LC\pc = Lc.elem;  
  121.     Lc.lenght = Lc.listsize; 
  122.     pc = Lc.elem; 
  123.     pa = La.elem; 
  124.     pb = Lb.elem; 
  125.     while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1]){ 
  126.         if (*pa <= *pb) *pc++ = *pa++; 
  127.         else *pc++ = *pb++; 
  128.     } 
  129.     while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩余元素  
  130.     while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩余元素  
  131.  
  132.  
  133. /************************************************************************/ 
  134. /* 打印list
  135. */ 
  136. /************************************************************************/ 
  137. void printList(SqList L){ 
  138.     printf("当前值:");  
  139.     for (int i =0; i<L.lenght;i++) { 
  140.         printf("%d ", *(L.elem+i)); // L.elem为首地址  
  141.     }  
  142.     printf("\r\n");  
  143.  
  144. void main() 
  145.     SqList La,Lb,Lc; 
  146.     ElemType e; 
  147.     int init,i; 
  148.     init = initList(La, LIST_INIT_SIZE); 
  149.     int data[6] = {5,3,6,2,7,4}; 
  150.     for (i=0; i<6;i++) { 
  151.         insertList(La,  data[i],  i); 
  152.     } 
  153.     printf("LA:\r\n");  
  154.     printList(La); 
  155.     deleteListElem(La, 3, e ); 
  156.     printList(La); 
  157.     insertList(La,  e,  3); 
  158.     printList(La); 
  159.  
  160.     //排序  
  161.     quickSort(La,0, La.lenght-1); 
  162.     printList(La); 
  163.  
  164.     printf("LB:\r\n");  
  165.     initList(Lb, LIST_INIT_SIZE); 
  166.     int Bdata[5] = {1,3,2,4,6}; 
  167.     for (i=0; i<5;i++) { 
  168.         insertList(Lb,  Bdata[i],  i); 
  169.     } 
  170.     //排序  
  171.     quickSort(Lb,0, Lb.lenght-1); 
  172.     printList(Lb); 
  173.  
  174.     mergeList(La, Lb,  Lc); 
  175.     printList(Lc); 
  176.  
// Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include "stdlib.h"
//宏定义
#define TRUE   1
#define FALSE   0
#define OK    1
#define ERROR   0
#define INFEASIBLE -1
#define OVERFLOW -2

#define LT(a,b)   ((a)<(b))
#define N = 100       

#define LIST_INIT_SIZE 100 //线性表初始空间分配量
#define LISTINCREMENT   10 //线性表空间分配的增量

typedef int Status;
typedef int ElemType;

typedef struct LNode{
	ElemType  *elem;        //存储空间的基地址
	int      lenght;		//当前的长度
	int		 listsize;      //当前分配的存储容量
}SqList;

/**
 *构造空的线性表
 */

Status initList(SqList &L, int lenght){
	if (lenght == 0) lenght = LIST_INIT_SIZE;
	L.elem = (ElemType *)malloc(lenght * sizeof(ElemType));
	if(!L.elem) exit(OVERFLOW);  //分配存储空间失败
	L.lenght = 0;				 //初始空表长度为0
	L.listsize = lenght ;//初始存储容量为100
	return OK;
}
/************************************************************************/
/* 在第i位置插入e
*/
/************************************************************************/
Status insertList(SqList &L, ElemType e, int i){
	ElemType *p,  *q;
	if(i<0 ||i > L.lenght) return ERROR;  //i值不合法
	if (L.lenght >= L.listsize) {
		ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType));
		if(!newbase) return OVERFLOW;	//存储分配失败  
		L.elem = newbase;				//新基值
		L.listsize += LISTINCREMENT;    //增加存储容量
	}
	q = &L.elem[i];						//q为插入的位置
	for (p = &L.elem[L.lenght]; p>=q; --p) {
		*p = *(p-1);					//i元素之后的元素往后移动
	}
	*q = e;								//插入e
	L.lenght +=1;
	return OK;

}
/************************************************************************/
/* 快速排序 
*/
/************************************************************************/
void sortList(SqList &L){
	

}
/************************************************************************/
/* 删除第i位置元素,并用e返回其值                                                                     */
/************************************************************************/
Status deleteListElem(SqList &L, int i, ElemType &e){
	int *p,  *q;
	if(i<0 ||i > L.lenght) return ERROR;  //i值不合法
	q = &L.elem[i];						  //被删除元素的位置为i,L.elem就是数组名,
	e = *q;								  //被删除元素的值赋值给e
	for (p = q; p< (L.elem + L.lenght); p++){ //元素左移
		*p = *(p+1);
	}
	--L.lenght;
	return OK;
}

/************************************************************************/
/*  快速排序
*/
/************************************************************************/

int partition(SqList &L, ElemType low, ElemType high){
	ElemType pivotkey = L.elem[low];		       //枢轴记录关键字
	while (low < high) {					 //从表的两端向中间扫描
		while (low < high &&  L.elem[high] >= pivotkey ) --high;//高端位置扫描
		L.elem[low] = L.elem[high];		//交换数据,小于pivotkey移到低端
		L.elem[high] = pivotkey;

		while (low < high && L.elem[low] <= pivotkey ) ++low;     //低端扫描
		L.elem[high] = L.elem[low];				  //交换数据 大于pivotkey移到高端
		L.elem[low] = pivotkey;									
	}
	return low;
}

void quickSort(SqList &L, ElemType low, ElemType high){
	int pivot;
	if(low < high) {										   
		pivot =  partition(L,  low,  high); 	
		quickSort(L,  low,  pivot -1);			//低端子表排序
		quickSort(L,  pivot +1, high);			//高端子表排序
	}
	
}


/************************************************************************/
/* 
合并两个线性表
*/
/************************************************************************/

void mergeList(SqList La, SqList Lb,  SqList &Lc){
	ElemType *pa, *pb, *pc;
	Lc.listsize =  La.lenght + Lb.lenght;
	initList(Lc, Lc.listsize);			//初始化LC\pc = Lc.elem;
	Lc.lenght = Lc.listsize;
	pc = Lc.elem;
	pa = La.elem;
	pb = Lb.elem;
	while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1]){
		if (*pa <= *pb) *pc++ = *pa++;
		else *pc++ = *pb++;
	}
	while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩余元素
	while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩余元素

}

/************************************************************************/
/* 打印list
*/
/************************************************************************/
void printList(SqList L){
	printf("当前值:"); 
	for (int i =0; i<L.lenght;i++) {
		printf("%d ", *(L.elem+i)); // L.elem为首地址
	} 
	printf("\r\n"); 
}

void main()
{
	SqList La,Lb,Lc;
	ElemType e;
	int init,i;
	init = initList(La, LIST_INIT_SIZE);
	int data[6] = {5,3,6,2,7,4};
	for (i=0; i<6;i++) {
		insertList(La,  data[i],  i);
	}
	printf("LA:\r\n"); 
	printList(La);
	deleteListElem(La, 3, e );
	printList(La);
	insertList(La,  e,  3);
	printList(La);

	//排序
	quickSort(La,0, La.lenght-1);
	printList(La);

	printf("LB:\r\n"); 
	initList(Lb, LIST_INIT_SIZE);
	int Bdata[5] = {1,3,2,4,6};
	for (i=0; i<5;i++) {
		insertList(Lb,  Bdata[i],  i);
	}
	//排序
	quickSort(Lb,0, Lb.lenght-1);
	printList(Lb);

	mergeList(La, Lb,  Lc);
	printList(Lc);

}


3. 线性表的链表表示LinkedList

一般使用链表 来描述。

优点:对于新增和删除操作add和remove和方便。不需要移动元素。

缺点:不方便随机访问元素,LinkedList要移动指针

代码实现:

  1. // Test.cpp : Defines the entry point for the console application.  
  2. //  
  3. #include "stdafx.h"  
  4. #include <stdio.h>  
  5. #include "stdlib.h"  
  6. //宏定义  
  7. #define TRUE   1  
  8. #define FALSE   0  
  9. #define OK    1  
  10. #define ERROR   0  
  11. #define INFEASIBLE -1  
  12. #define OVERFLOW -2  
  13.  
  14. #define LT(a,b)   ((a)<(b))  
  15. #define N = 100         
  16.  
  17. typedef int Status; 
  18. typedef int ElemType; 
  19.  
  20. typedef struct LNode{ 
  21.     ElemType  data;              
  22.     struct LNode   *next;    
  23. }LNode, *LinkList; 
  24.  
  25. /************************************************************************/ 
  26. /*
  27. 初始化链表
  28. */ 
  29. /************************************************************************/ 
  30. Status initList(LinkList &L){ 
  31.     /*单链表的初始化*/ 
  32.     L = (LinkList)malloc(sizeof(LNode));    //申请一个头节点  
  33.     if(!L) exit(OVERFLOW);          //申请空间失败    
  34.     L->next=NULL;                //建立一个带都节点的空链表  
  35.     return OK; 
  36.  
  37.     /*
  38.     需要改变指针的指针,所以参数必须是引用或者是 *L:
  39.     (*L) = (Lnode *)malloc(sizeof(Lnode));
  40.     (*L)->next=NULL;
  41.     return 1;                                                                    
  42.     */ 
  43.  
  44.  
  45. /************************************************************************/ 
  46. /*    
  47. 创建链表
  48. */ 
  49. /************************************************************************/ 
  50. void createList(LinkList L, int n){ 
  51.     /*单链表的初始化*/ 
  52.     if (!L) { 
  53.         initList(L); 
  54.     } 
  55.     ElemType data; 
  56.     LinkList p,q = L; 
  57.     printf("输入节点数据的个数%d:\r\n", n); 
  58.     for(int i = 0; i<n; i++) { 
  59.         p = (LinkList) malloc( sizeof(LNode)); //申请一个新节点  
  60.         scanf("%d",&data); 
  61.         p->data = data; 
  62.         p->next = q->next; 
  63.         q->next = p; 
  64.         q = p; 
  65.     } 
  66. /************************************************************************/ 
  67. /* 在第i位置插入e
  68. */ 
  69. /************************************************************************/ 
  70. Status insertList(LinkList L, ElemType e, int i){ 
  71.     LinkList s, p = L; 
  72.     int j = 0; 
  73.     while (p && j<i){                //寻找i节点  
  74.         p = p->next; 
  75.         j++; 
  76.     } 
  77.     if (!p ||j >i) return ERROR; 
  78.     s = (LinkList) malloc(sizeof(LNode));       //生成新节点  
  79.     s->data = e; s->next = p->next;            //插入L中  
  80.     p->next = s; 
  81.     return OK; 
  82.  
  83.  
  84. /************************************************************************/ 
  85. /* 删除第i位置元素,并用e返回其值                                                                     */ 
  86. /************************************************************************/ 
  87. Status deleteListElem(LinkList L, int i, ElemType &e){ 
  88.     LinkList p, q; 
  89.     int j = 0; 
  90.     p = L; 
  91.     while (p && j<i){ 
  92.         p = p->next; 
  93.         ++j; 
  94.     } 
  95.     if (!p->next || j>i)  return ERROR;   //删除的位置不对  
  96.     q  = p->next; p->next = q->next; 
  97.     e = q->data; free(q);            //释放节点  
  98.     return OK; 
  99.  
  100.  
  101. /************************************************************************/   
  102. /*  插入排序
  103. */   
  104. /************************************************************************/   
  105.  
  106. void  InsertSort(LinkList L) 
  107.     LinkList  list;             /*为原链表剩下用于直接插入排序的节点头指针*/ 
  108.     LinkList  node;             /*插入节点*/ 
  109.     LinkList  p;         
  110.     LinkList  q;         
  111.  
  112.     list = L->next;              /*原链表剩下用于直接插入排序的节点链表*/ 
  113.     L->next = NULL;              /*只含有一个节点的链表的有序链表。*/ 
  114.     while (list != NULL)   {    /*遍历剩下无序的链表*/ 
  115.         node = list, q = L;    
  116.         while (q && node->data > q->data  ) { 
  117.             p = q; 
  118.             q = q->next; 
  119.         } 
  120.          
  121.         if (q == L) {  /*插在第一个节点之前*/ 
  122.             L = node; 
  123.         }  else {     /*p是q的前驱*/ 
  124.             p->next = node;    
  125.         } 
  126.         list = list->next; 
  127.         node->next = q; /*完成插入动作*/ 
  128.  
  129.     } 
  130.  
  131.  
  132.  
  133. /************************************************************************/ 
  134. /*
  135. 合并两个线性表
  136. */ 
  137. /************************************************************************/ 
  138.  
  139. void mergeList(LinkList  &La, LinkList  &Lb,  LinkList &Lc){ 
  140.     LinkList pa, pb, pc; 
  141.     pa  = La->next; 
  142.     pb  = Lb->next; 
  143.     Lc =  pc = La; 
  144.     while (pa && pa) { 
  145.         if (pa->data > pb->data) { 
  146.             pc->next = pb; 
  147.             pc = pb; 
  148.             pb =pb->next; 
  149.         }else
  150.             pc->next = pa; 
  151.             pc = pa;  
  152.             pa =pa->next; 
  153.         } 
  154.     } 
  155.     pc->next = pa? pa :pb; 
  156.     free(Lb); 
  157.  
  158. /************************************************************************/ 
  159. /* 打印list
  160. */ 
  161. /************************************************************************/ 
  162. void printList(LinkList  L){ 
  163.     printf("当前值:"); 
  164.     LinkList p; 
  165.     p = L->next; 
  166.     while(p){ 
  167.         printf("%d ", p->data);  
  168.         p = p->next; 
  169.     } 
  170.     printf("\r\n");  
  171.  
  172. void main() 
  173.     LinkList  La,Lb,Lc; 
  174.     ElemType e; 
  175.     int init,i; 
  176.     printf("LA:\r\n");   
  177.     initList(La); 
  178.     createList(La, 5); 
  179.     insertList(La, 7,  3);   
  180.     printList(La); 
  181.     deleteListElem(La, 3,  e);   
  182.     printList(La); 
  183.     InsertSort(La); 
  184.     printList(La); 
  185.  
  186.     printf("Lb:\r\n");   
  187.     initList(Lb); 
  188.     createList(Lb, 4); 
  189.     InsertSort(Lb); 
  190.     printList(Lb); 
  191.  
  192.     printf("Lc:\r\n");  
  193.     initList(Lc); 
  194.     mergeList(La,   Lb,   Lc); 
  195.     printList(Lc); 
  196.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值