自己总结的一些常数据结构基础知识

1  


排序方法   平均情况  最好   最坏   辅助空间  稳定性
冒泡                       N*N         1
简单选择                    N*N        1
直接插入                    N*N        1
希尔                                   1         不稳定                    堆                          N*ln      1          不稳定
归并                        N*ln       n
快速                         N*N        n       不稳定






下列的排序算法中,初始数据集的排列顺序对算法的性能无影响的是(B)
A、插入排序    B、堆排序    C、冒泡排序    D、快速排序


在操作系统中最常用来被作为存储文件关系的数据结构是(D)
A、链表       B、数组        C、堆栈       D、树


在一个具有n个顶点的无向图中,要连通全部顶点至少需要(B)条边。
A、N    B、N-1    C、N+1     D、N/2


下面哪一种操作不是 stack 的基本操作?(D)
A、入栈    B、出栈    C、检查是否为空    D、排序栈中元素


请问对一个排好序的数组进行查找,时间复杂度为(B)
A、O(n)            B、O(lgn)        C、O(nlgn)          D、O(1)
以下排序算法是非稳定排序的是(BCD)
A、冒泡排序      B、归并排序       C、快速排序         D、堆排序      E、希尔排序


一个栈的入栈序列是A、B、C、D、E,则栈的不可能的输出序列是(C)
A、EDCBA       B、DECBA     C、DCEAB     D、ABCDE


下面哪项不是链表优于数组的特点?(D)
A、方便删除     B、方便插入    C、长度可变    D、存储空间小


下列四种排序中(A)的空间复杂度最大
A、快速排序        B、冒泡排序       C、希尔排序         D、堆


以下关于链式存储结构的叙述中哪一条是不正确的C
A、结点除自身信息外还包括指针域,因此存储密度小于顺序存储结构
B、逻辑上相邻的结点物理上不必邻接
C、可以通过计算直接确定第i个结点的存储地址
D、插入、删除运算操作方便,不必移动结点
存储密度=(结点数据本身占的存储量)/(结点整体占的数据量)


设一棵二叉树的深度为k,则该二叉树最多有(D)个节点。
A、2k-1      B、2^k    C、2^(k-1)      D、2^k-1


对初始状态为递增序列的数组按递增顺序排序,最省时间的是插入排序算法,最费时间的算法(B)
A、堆排序  B、快速排序   C、插入排序   D、归并排序


在有序双向链表中定位删除一个元素的平均时间复杂度为(A)
A、O(1)   B、O(N)   C、O(logN)      D、O(N*logN) 


判断一个单向链表中是否存在环的最佳方法是(B)
A、两重遍历      B、快慢指针      C、路径记录       D、哈希表辅助


按照升序排列的一组数据123456798,下面哪种排序法在空间和时间上最优?C
A、快速排序             B、冒泡排序             C、插入排序             D、堆排序


(  C  )49. 下述几种排序方法中,要求内存最大的是
A. 插入排序      B.快速排序        C. 归并排序       D. 选择排序


(  B  )45.堆是一种       排序。
A. 插入       B.选择        C. 交换       D. 归并




(  A&D )41.在最好情况下,下列排序算法中       排序算法所需比较关键字次数最少。
A.冒泡       B.归并       C.快速         D.直接插入


(  C  )34. 排序方法中,从未排序序列中依次取出元素与已排序序列(初始时为空)中的元素进行比较,将其放入已排序序列的正确位置上的方法,称为
A. 希尔排序      B. 冒泡排序        C. 插入排序       D. 选择排序


数据库里建索引常用的数据结构是(C)
A、链表                         B、队列                       C、树                             D、哈希表


链表不具备的特点是 __A__ 。
A 可随机访问任何一个元素              B 插入、删除操作不需要移动元素
C 无需事先估计存储空间大小              D 所需存储空间与线性表长度成正比


一个栈的输入序列为123.....n,若输出序列的第一个元素是n,输出第i(1<=i<=n)个元素是(B)
A、不确定
B、n-i+1
C、i
D、n-i


在排序方法中,元素比较次数与元素的初始排列无关的是(D)
A、Shell 排序         B、归并排序              C、直接插入排序                D、选择排序
A、C肯定不选的,归并排序的在merge中是跟序列有关,如果有序,比较次数最少n/2,最糟是元素错落n-1。而选择排序比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。所以 应该是选择排序!


当很频繁地对序列中部进行插入和删除操作时,应该选择使用的容器是(B)
A、vector     B、list      C、deque      D、stack


外部排序常用的算法? A
A、归并排序       B、快速排序         C、堆排序        D、希尔排序


 在对空间和时间都有限制的实时系统中,常使用的排序算法?B 
A、插入排序          B、堆排序          C、快速排序          D、归并排序


已知一个线性表(38,25,74,63,52,48),假定采用散列函数h(key) = key%7计算散列地址,并散列存储在散列表A【0....6】中,若采用线性探测方法解决冲突,则在该散列表上进行等概率成功查找的平均查找长度为(C)


A、1.5                  B、1.7                 C、2.0         D、2.3


串ababaaababaa的next的函数值为(C)。KMP算法中的next数组
A.012345678999
B  012121111212
C.011234223456
D.0123012322345
T ababaaaba   011234223
T abcabx         011123


若查找每个记录的概率均等,则在具有n个记录的连续顺序文件中采用顺序查找法查找一个记录,其平均查找长度ASL为(C)
A.(n1)/2    B.n/2     C.(+1)/2
D.n


将长度为n的单链表接到长度为m的单链表后面的算法的时间复杂度为 (C) 。
       A.O(1)     B.O(n)   C.O(m)    D.O(n+m)




1.适用于折半查找的表的存储方式及元素排列要求为(?D???)???
??A.链接方式存储,元素无序?????B.链接方式存储,元素有序?C.顺序方式存储,元素无序?????D.顺序方式存储,元素有序






在待排序的元素序列基本有序的前提下,效率最高的排序方法是(冒泡排序)?
在最坏情况下,下列顺序方法中时间复杂度最小的是(堆排序)?
希尔排序法属于(插入类排序)?
堆排序法属于(选择类排序)
在下列几种排序方法中,要求内存量最大的是(归并排序)?
已知数据表A中每个元素距其最终位置不远,为节省时间,应采用(直接插入排序)
与单向链表相比,双向链表的优点之一是(更容易访问相邻结点)






在单链表中,增加头结点的目的是(方便运算的实现) 
9.循环链表的主要优点是(从表中任一结点出发都能访问到整个链表)








2


A
结构之美:判断单链表中是否有环
方法1:使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p == q,则存在环。
void Isloop(Llink head)
{
 if(!head||!head->next)
  return;
 Llink p,q;
 bool loop=false;
 p=q=head->next;
 while(q&&q->next)//判断是否有环
 {
  p=p->next;
  q=q->next->next;
  if(p==q)
  {
   loop=true;
   break;
  }
 }




B
如何求数组中只出现一次的数  其他出现两次 
给定一个数组 里面只有一个数出现奇数次  其他为偶数次  找出这个元素


int findnotdoulble{
int  result =a[0];
int i;
for(i=1;i<n;i++)
{
result^=a[i];


}
return result


}






C
一个for循环打印二维数组    三维数组


int a[x][y]


for(i=0;i<x*y;i++)


printf("%d\n",a[i/x][i%y])






int a[x][y][z]


for(i=0;i<x*y*z;i++)


printf("%d\n",a[i/yz][(i/z)%y][i%z])


  int row, column, table ,i;


   float values[2][3][5] = {
                            {{1.0, 2.0, 3.0, 4.0, 5.0},
                             {6.0, 7.0, 8.0, 9.0, 10.0},
                             {11.0, 12.0, 13.0, 14.0, 15.0}},


                            {{16.0, 17.0, 18.0, 19.0, 20.0},
                             {21.0, 22.0, 23.0, 24.0, 25.0},
                             {26.0, 27.0, 28.0, 29.0, 30.0}}
                           };


     for (i = 0; i< 30; i++)
      printf(" %f\n",values[i/15][(i/5)%3][i%5]);






D


如何判断一个整数X可以表示N(N>=2)个连续整数和  


  int m=0,n=0,start=0,end=0,flag=0;
  float temp=0.0;
printf("请输入被分解的数:");
    scanf("%d",&m);
    printf("请输入被分解的个数:");
    scanf("%d",&n);
  temp=(float)m/n-(float)(n-1)/2;


  if(temp==(int)temp)
  {
  for(flag=1,start=(int)temp,end=start+n;start<end;start++)
     printf("%d ",start);
     printf("\n");
  
  }
 if(flag==0)
 printf("没有符合条件的数\n");




E  计算两个有序整数数组的交集


int a1[5]={0,1,2,3,4};
int a2[5]={1,3,5,7,9};
int i=0,j=0,k=0;
int p[5];
while(i<5&&j<5)
{
if(a1[i]==a2[j])
{
p[k++]=a1[i];  
    i++;
j++;


}
 
else if(a1[i]>a2[j])
j++;
else if(a1[i]<a2[j])
i++;
 
 
}


for(i=0;i<k;i++)
{
printf("%d\n",p[i]);
}






3
ASCII码


ASCII码表
ASCII码大致可以分作三部分組成。
第一部分是:ASCII非打印控制字符; 
第二部分是:ASCII打印字符; 
第三部分是:扩展ASCII打印字符。
第一部分:ASCII非打印控制字符表
ASCII表上的数字0–31分配给了控制字符,用于控制像打印机等一些外围设备。例如,12代表换页/新页功能。此命令指示打印机跳到下一页的开头。(参详ASCII码表中0-31)
第二部分:ASCII打印字符
数字 32–126 分配给了能在键盘上找到的字符,当您查看或打印文档时就会出现。数字127代表 DELETE 命令。(参详ASCII码表中32-127)
第三部分:扩展ASCII打印字符
扩展的ASCII字符满足了对更多字符的需求。扩展的ASCII包含ASCII中已有的128个字符(数字0–32显示在下图中),又增加了128个字符,总共是256个。即使有了这些更多的字符,许多语言还是包含无法压缩到256个字符中的符号。因此,出现了一些ASCII的变体来囊括地区性字符和符号。例如,许多软件程序把ASCII表(又称作ISO8859-1)用于北美、西欧、澳大利亚和非洲的语言。


A=65 a=97 类推


查找每个字符出现的次数 


char *str="AbcABca";
 int  count[256]={0};
 for(char *p=str;*p;p++)
count[*p]++;
  for(int i=0;i<256;i++)
  {
  if(count[i]>0)
 printf("the count of %c is :%d\n",i,count[i]);
  
  
  }












如何检查字符是否为整数  如果是  返回整数值
#include "stdafx.h"
#include  "mylei.h"
#include     <ctype.h>


int cheak(int p)
{


int c=p;


if(isdigit(p))
  {
   c=p-48;
  }


return c;


}


void  main()


{
int c; 
while((c=getchar())!=EOF)
//EOF 这个结束标志不是键盘上的字符       而是一个组合按键 ctrl +z
{


getchar();//缓冲作用   回车符
c=cheak(c);
if(isalpha(c))
printf("不是\n");
else 
printf("是:%\n",c);




}
getchar();
getchar();


}




如何将字符串逆序


#include "stdafx.h"
#include  "mylei.h"
#include     <ctype.h>




char *reverse(char *s)
{
char *p=s;
char *q=s;
while(*q)
 ++q;
q--;//p在头  q在尾


while(q>p)
{char t = *p;
 *p=*q;
 p++;
 *q=t;
 q--;
}
return  s;










}


void  main()


{
char a[]="abcd";
int len=sizeof(a)/sizeof(a[0]);
printf("%s\n",reverse(a));


getchar();
getchar();


}








4




A
typedef  struct
{char name[20];
int age}person;
的意思是为匿名结构体struct{char name[20];int age};起一个“别名”叫person,
以后在代码中写person a,*b;就是声明了一个此结构体变量和此结构体指针。


例子:


struct list
{
int t;
list *next;
};
定义 struct list  a;


typedef struct list
{


int t;
list *next;


}List;


定义  List a;




B




第一种输入方式
s=(char *)malloc(100*sizeof(char));
scanf("%s",s);


朴素的模式匹配法


#include "stdafx.h"
#include  "mylei.h"
#include     <ctype.h>
#include "string.h"




int index(char *S, char *T )
{
 int pose=0;
 int i=0;
 int j=0;
 while((i<strlen(S))&&(j<strlen(T)))
 {
 if(S[i]==T[j])
 {i++;
 j++;}
 else
 {
 i=i-j+1;
 j=0;
 }
 
 
 }


if(j>=strlen(T))
 return i-strlen(T);
else 
  return 0;


}


void  main()


{    int m;
char    s[20];
char t[20];


scanf("%s",s);
scanf("%s",t);


m=index(s,t);
printf("%d\n",m);
getchar();
getchar();


}




第二种输入方式
#include <stdio.h> 
#include <stdlib.h> 
int main()
{
    int i = 1;
    char ch, *p;
    p = (char*)malloc(sizeof(char)); //先分配一点内存 
    while( (ch = getchar()) != '\n' )
    {//从输入流中循环获取字符, 直到换行为止 
        i++; 
        p = (char*)realloc(p, sizeof(char)*i);    //扩增内存空间 
        *(p+i-2) = ch;                            //保存输入的字符 
        *(p+i-1) = '\0';                        //添加字符串结束符 
    }
    printf("%s\n", p); //打印字符串 
    return 0; 







朴素模式识别法




#include "stdafx.h"


#include     <ctype.h>
#include "string.h"
#include <stdio.h> 
#include <stdlib.h> 


int index(char *S, char *T )
{
 int pose=0;
 int i=0;
 int j=0;
 while((i<strlen(S))&&(j<strlen(T)))
 {
 if(S[i]==T[j])
 {i++;
 j++;}
 else
 {
 i=i-j+1;
 j=0;
 }
 
 
 }


if(j>=strlen(T))
 return i-strlen(T);
else 
  return 0;


}


void  main()


{   


int m;
char    *s;
char   *t;


    int n = 1;
    char ch;
    s = (char*)malloc(sizeof(char));              //先分配一点内存 
    while( (ch = getchar()) != '\n' )
       {                                          //从输入流中循环获取字符, 直到换行为止 
         n++; 
        s = (char*)realloc(s, sizeof(char)*n);    //扩增内存空间 
        *(s+n-2) = ch;                            //保存输入的字符 
        *(s+n-1) = '\0';                          //添加字符串结束符 
       }






     n=1;
    t= (char*)malloc(sizeof(char));            //先分配一点内存 
    while( (ch = getchar()) != '\n' )
      {                                            //从输入流中循环获取字符, 直到换行为止 
        n++; 
        t= (char*)realloc(t, sizeof(char)*n);     //扩增内存空间 
        *(t+n-2) = ch;                            //保存输入的字符 
        *(t+n-1) = '\0';                         //添加字符串结束符 
      }










m=index(s,t);
printf("%d\n",m);
getchar();
getchar();


}










5




A 单链表


链表的创建和插入 删除


#include "stdafx.h"
#include "string.h"
#include <stdio.h> 
#include <stdlib.h> 


#define   ERROR   0
#define  NULL  0
typedef  struct Node //定义节点
{
int data;
struct Node  *next;
}Node;


Node  *createlist(Node *p,int n)//创建链表
{


Node  *head;


p=(Node *)malloc(sizeof(Node));
p->data=100;
p->next=NULL;


int i=0;


for(i=0;i<n;i++)
{
head=(Node *)malloc(sizeof(Node));
head->data=i;
head->next=p->next;
p->next=head;
}


return  p;


}


int  insert(Node *p,int m ,int e)// 插入一个节点
{


Node *s;


int j=0;
while(p&&j<m)
{
p=p->next;
++j;


}


if(!(p->next||j>m))
return ERROR;




s=(Node *)malloc(sizeof(Node));
s->data=e;
s->next=p->next;
p->next=s;


}


int  del(Node *H,int f)
{   Node *p;
int j=0;
while(H&&j<f)
{
H=H->next;
++j;
}


if(!(H->next||j>f))
return ERROR;


p=H->next;
H->next=p->next;
free(p);




}




void  main()


{   
Node *L=NULL;
Node  *g=NULL;//定义时候初始化指针少很多问题
L=createlist(g , 7);
insert(L,2,8);
del(L,2);
while(L!=NULL)
{
printf("%d\n",L->data);
L=L->next;


}


printf("删除后\n");






getchar();
getchar();


}









循环链表
链表的创建和插入 删除


#include "stdafx.h"
#include "string.h"
#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h>


#define   ERROR   0
#define  NULL  0
typedef  struct Node //定义节点
{
int data;
struct Node  *next;
}Node;


Node  *createlist(Node *p,int n)//创建链表
{


Node  *head;
p=(Node *)malloc(sizeof(Node));
p->data=100;
p->next=NULL;
int i=0;
for(i=0;i<n;i++)
{

head=(Node *)malloc(sizeof(Node));
head->data=i;
head->next=p->next;
p->next=head;


}


//现在已经建好了单链表
//下面开始循环链表


Node *xh;
xh=(Node *)malloc(sizeof(Node));
xh=p;
while(xh->next)
{
xh=xh->next;
}


xh->next=p;


return  p;


}








int  insert(Node *p,int m ,int e)// 插入一个节点
{


Node *s;


int j=0;
while(p&&j<m)
{
p=p->next;
++j;


}


if(!(p->next||j>m))
return ERROR;




s=(Node *)malloc(sizeof(Node));
s->data=e;
s->next=p->next;
p->next=s;


}


int  del(Node *H,int f)
{   Node *p;
int j=0;
while(H&&j<f)
{
H=H->next;
++j;
}


if(!(H->next||j>f))
return ERROR;


p=H->next;
H->next=p->next;
free(p);




}




void  main()


{   
Node *L=NULL;
Node  *g=NULL;//定义时候初始化指针少很多问题
L=createlist(g , 7);
insert(L,2,8);
del(L,2);
while(L!=NULL)
{
printf("%d\n",L->data);
L=L->next;
Sleep(1000);


}


printf("删除后\n");






getchar();
getchar();


}









双向链表


结构体定义


typedef struct  Node
{
int data;
struct Node *next;
struct Node  *pre;
}Node;


插入S操作


S->pre=p;
s->next=p->next;
p->next->pre=s;
p->next=s;


删除P(中间)操作


p->pre->next=p->next;
p->next->pre=p->pre;
free(p);




先建立一个顺向链表   再建立反向链表   这样就完成了


例程


#include "stdafx.h"
#include "string.h"
#include <stdio.h> 
#include <stdlib.h> 
 #include <windows.h>


//打印选项
void printTheSelect()
{
    printf("\n1.初始化双向链表\n2.打印双向链表\n3.逆序打印双向链表\n");
    printf("4.求链表长度\n5.判断链表是否为空\n6.清空链表\n");
    printf("7.插入元素\n8.删除元素\n9.删除链表\n0.退出\n");
}


typedef struct DuLnode
{
    int data;              //数据
    struct DuLnode *prior; //前驱
    struct DuLnode *next;  //后继
}DuLnode,*DuLinkList;


//初始化双向链表
void initDlist(DuLinkList &L)
{
    char x;          //定义成char型是用于输入'q'时可以退出,其实定义成int也能退出
    DuLinkList p,q;


    L = (DuLinkList)malloc(sizeof(DuLnode));
    L->next = NULL;
    L->prior = NULL;        //构造头结点
    p = L;
    
    printf("输入双向链表的元素,每输入一个元素后按回车,输入q表示结束.\n");
    fflush(stdin);   //清空输入缓冲区
    x=getchar();
    while( x != 'q')
    {
        q = (DuLinkList)malloc(sizeof(DuLnode));
        q->data = x - 48;  //得到的是输入字符的ASCII码,减去30H就变成想要的数字,十六进制30h即为十进制48
        q->next = NULL;
        q->prior = p;
        p->next = q;
        p = q;
        fflush(stdin);
        x=getchar();
    }
    if( x == 'q' )
    {
        printf("双向链表构造完毕!\n");
    }


}


//打印双向链表
void printDlist(DuLinkList &L)
{
    DuLinkList p;
    
    if(L == NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else if(L->next == NULL)
    {
        p = L->next;
        printf("链表为空!\n");
    }
    else
    {
        p = L->next;
        while(p)
        {
            printf("%d ",p->data);
            p = p->next;
        }
    }
}


//逆序打印双向链表
void printDlistFromLast(DuLinkList &L)
{
    DuLinkList p;
    
    if(L == NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else if( L->next == NULL )
    {
        p = L->next;
        printf("链表为空!\n");
    }
    else
    {
        p = L->next;
        while(p->next)
        {
            p = p->next;
        }


        while(p->prior)
        {
            printf("%d ",p->data);
            p = p->prior;
        }
    }
}


//求链表长度
int lengthDlist(DuLinkList &L)
{
    int i = 0;


    if(L == NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else
    {
        DuLinkList p = L->next;
        while(p)
        {
            i++;
            p = p->next;
        }
    }


    return i;
}


//判断链表是否为空
void isEmptyOrNotDlist(DuLinkList &L)
{
    if(L == NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else if( L->next == NULL )
    {
        printf("链表为空!\n");
    }
    else
    {
        printf("链表非空!\n");
    }
}


//把双向链表置空
void clearTheDlist(DuLinkList &L)
{
    if(L==NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else
    {
        DuLinkList p,q;
        p = q = L->next;   //是p、q指向第一个元素
        L->next = NULL;


        while(p)          //逐个释放元素所占内存
        {
            p = p->next;
            free(q);
            q = p;
        }
    }
}


//删除双向链表
void delTheDlist(DuLinkList &L)
{
    clearTheDlist(L);
    free(L);
    L = NULL;
}


//在双向链表中第i个位置后面插入元素m
void insertElmToDlist(DuLinkList &L)
{
    int i,m;
    printf("输入插入的元素:\n");
    scanf("%d",&m);
    printf("输入插入的位置:\n");
    scanf("%d",&i);
    DuLinkList p,q;
    p = L;
    int j = 0;
    
    if(L == NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else if(L->next == NULL)
    {
        printf("链表为空,请初始化后再进行插入数据操作!\n");
    }
    else if( i<1 || i>lengthDlist(L)+1 )
    {
        printf("插入位置错误!\n");
    }
    else
    {
        while( j<i )
        {
            p = p->next;
            j++;
        }
        
        if( j == lengthDlist(L) )      //如果在最后一个元素后面插入m
        {
            q = (DuLinkList)malloc(sizeof(DuLnode));
            q->data = m;
            q->next = NULL;
            q->prior = p;
            p->next = q;
        }
        else
        {
            q = (DuLinkList)malloc(sizeof(DuLnode));
            q->data = m;
            q->next = p->next;
            p->next->prior = q;
            p->next = q;
            q->prior = p;
        }
    }
}


//删除双向链表中的第i个元素
void delElmFromDlist(DuLinkList &L)
{
    int i;
    printf("输入要删除的位置:");
    scanf("%d",&i);
    int j = 0;
    DuLinkList p = L;
    
    if(L == NULL)
    {
        printf("链表不存在,请先初始化!\n");
    }
    else if( i<1 || i>lengthDlist(L) )
    {
        printf("删除的位置不存在!\n");
    }
    else
    {
        while( j<i )
        {
            p = p->next;
            j++;
        }


        if( j == lengthDlist(L) )
        {
            p->prior->next = NULL;
            free(p);
        }
        else
        {
            p->prior->next = p->next;
            p->next->prior = p->prior;
            free(p);
        }
    }
}




int main()
{
    int i;
    DuLinkList L = NULL;
    printTheSelect();
    printf("请输入操作:");
    scanf("%d",&i);
    while( 0 != i)
    {
        switch(i)
        {
        case 1:initDlist(L);
            break;
        case 2:printDlist(L);
            break;
        case 3:printDlistFromLast(L);
            break;
        case 4:printf("链表长度为:%d\n",lengthDlist(L));
            break;
        case 5:isEmptyOrNotDlist(L);
            break;
        case 6:clearTheDlist(L);
            break;
        case 7:insertElmToDlist(L);
            break;
        case 8:delElmFromDlist(L);
            break;
        case 9:delTheDlist(L);
            break;
        default:printf("输入错误,请重新输入!\n");
            break;
        }
        printTheSelect();
        printf("请输入操作:");
        scanf("%d",&i);
    }
    if(0 == i)
    {
        printf("程序退出....\n");
    }
    


getchar();
getchar();


}






6  栈与队列


A
栈:
出栈 进栈 


#include "stdafx.h"
#include "string.h"
#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h>




typedef struct Node 
{


int a;
struct Node *next;


}Node;




 struct linkstack
{
Node *top;
int count;
};




int push(struct linkstack *p,int e)
{


Node *s=(Node *)malloc(sizeof(Node));
s->a=e;
s->next=p->top;
p->top=s;
p->count++;
return 1;
}


 struct linkstack * pop( struct linkstack *k)
{
  
  Node  *m=( Node *)malloc(sizeof( Node));
         
m=k->top;
         k->top=k->top->next;
         free(m);
         k->count--;
      
  return  k;
    
}




int main()
{  
int i;
    int e=0;
    struct linkstack  *L;
   L=( struct linkstack *)malloc(sizeof( struct linkstack));
   L->count=0;


   for(i=0;i<16;i++) //进栈
    {
   push(L,i);
    }




   printf("%d\n",L->count);
   printf("%d\n",L->top->a);




 for(i=0;i<5;i++)//连续出栈5次
    {
         printf("%d\n",L->top->a);
L=pop(L);


         }
   
getchar();
getchar();


}




B


队列;
出队与入队


#include "stdafx.h"
#include "string.h"
#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h>


//队定义
typedef  struct Node
{
int data;
struct Node *next;


}Node;


typedef struct que 
{
Node *front; 
Node  *rear;
}que;


que * init(que *Q)
{


   if(!Q)  
    {  
        return false;  
    }  
  Q->front = NULL; 
  Q->rear=NULL; 
   


return Q;
}


que * ruque(que *Q,int e)


{
 Node *s;
 s=(Node *)malloc(sizeof(Node));
  
s->data=e;
s->next=NULL;




if(Q->rear==NULL)
{
Q->front=s;
Q->rear=s;


}
else
{
Q->rear->next=s;
Q->rear=s;
}
return Q;
}


que * delque(que *Q)
{
Node * p;
p=Q->front;


Q->front=p->next;


if(Q->rear==p)
{
Q->rear=Q->front;
}
free(p);
return Q;


}


int main()

    int i;
    que *duilie;
    duilie=(que *)malloc(sizeof(que));
    duilie=init(duilie);//队列初始化




 
for(i=0;i<10;i++)//入队操作
{
           duilie=ruque(duilie,i) ;
  printf("%d\n",duilie->rear->data);
}
   
        for(i=0;i<3;i++)//出队操作
{
           printf("%d\n",duilie->front->data);
           duilie=delque(duilie);
}






    getchar();
    getchar();






}




经典的网上例子


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std;  
  
typedef int SElemType;  
  
struct Node  
{  
    SElemType data;  
    struct Node* next;  
};  
  
typedef struct {  
    Node* front;  
    Node* rear;  
}LinkQueue;  
  
//初始化队列  
bool InitQueue(LinkQueue* &queue)  
{  
    queue = new LinkQueue();  
    if(!queue)  
    {  
        return false;  
    }  
    queue->front = NULL;  
    queue->rear  = NULL;  
    return true;  
}  
  
//入队列  
void EnQueue(LinkQueue* &queue,SElemType e)  
{  
    Node* node = new Node();  
    node->data = e;  
    node->next = NULL;  
    //如果队列为空  
    if(queue->rear == NULL)  
    {  
        queue->front = node;  
        queue->rear  = node;  
    }  
    else//如果队列不为空  
    {  
        queue->rear->next = node;  
        queue->rear = node;  
    }     
}  
  
//出队列  
SElemType DeQueue(LinkQueue* &queue)  
{  
    if(queue->front == NULL)  
    {  
        return -1;  
    }  
    else  
    {  
        SElemType elem;  
        Node* node = queue->front;  
        elem = node->data;  
        if(queue->front->next == NULL)  
        {  
            queue->front = NULL;  
            queue->rear  = NULL;  
        }  
        else  
        {  
            queue->front = queue->front->next;  
        }  
        delete node;  
        return elem;  
    }  
}  
  
//获得队列头元素  
SElemType GetHead(LinkQueue* &queue)  
{  
    if(queue->front!=NULL)  
    {  
        return queue->front->data;  
    }  
    else  
        return -1;  
}  
  
//判断队列空  
bool empty(LinkQueue* &queue)  
{  
    if(queue->front == NULL)  
        return true;  
    else  
        return false;  
}  
  
//求队列长度  
int QueueLength(LinkQueue* &queue)  
{  
    int i = 0;  
    Node* p = queue->front;  
    while(p!=NULL)  
    {  
        i++;  
        p = p->next;  
    }  
    return i;  
}  
  
//清空队列  
void ClearQueue(LinkQueue* &queue)  
{  
    if(queue->front == NULL)  
    {  
        return;  
    }  
    else  
    {  
        Node* p = queue->front;  
        Node* q = p->next;  
        while(q)  
        {  
            delete p;  
            p = NULL;  
            p = q;  
            q = q->next;  
        }  
        delete p;  
        p = NULL;  
        queue->front = NULL;  
        queue->rear  = NULL;  
    }  
}  
  
//销毁队列  
void DestroyQueue(LinkQueue* &queue)  
{  
    ClearQueue(queue);  
    delete queue;  
    queue = NULL;  
}  
  
//显示队列  
void PrintQueue(LinkQueue* &queue)  
{  
    Node* p = queue->front;  
    while(p)  
    {  
        cout<<p->data<< " ";  
        p = p->next;  
    }  
    cout << endl;  
}  
  
void main()  
{  
    LinkQueue* queue;  
    InitQueue(queue);  
    EnQueue(queue,3);  
    EnQueue(queue,4);  
    EnQueue(queue,5);  
    PrintQueue(queue);  
    cout<< GetHead(queue) << endl;  
    cout<< DeQueue(queue) << endl;  
    DestroyQueue(queue);  
getchar();
getchar();
}  











二叉树
二叉树的建立和遍历


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std;  
#define  ERROR 0;


struct  Bittree
{
 int data;
 struct Bittree *Lchirld;
 struct Bittree *Rchirld;
};


struct Bittree * create()
{


char c;
struct Bittree * T;
scanf("%c",&c);
if(c=='#')
  T=NULL;
else 
{
T=(struct Bittree *)malloc(sizeof(struct Bittree));
T->data=c;
T->Lchirld=create();
T->Rchirld=create();
}
return  T;




}


void qianli(struct Bittree *p)
{


if(p==NULL)
return;
printf("%c\n",p->data);
qianli(p->Lchirld);
qianli(p->Rchirld);




}


void main()  
{  


struct Bittree *TT;
TT=create();
qianli(TT);
getchar();
getchar();
}  






C 求二叉树的深度  递归思想
#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std;  
#define  ERROR 0;


struct  Bittree
{
 int data;
 struct Bittree *Lchirld;
 struct Bittree *Rchirld;
};


struct Bittree * create()
{
char c;
struct Bittree * T;
scanf("%c",&c);
if(c=='#')
  T=NULL;
else 
{
T=(struct Bittree *)malloc(sizeof(struct Bittree));
T->data=c;
T->Lchirld=create();
T->Rchirld=create();
}
return  T;
}


void qianli(struct Bittree *p)
{
if(p==NULL)
return;
printf("%c\n",p->data);
qianli(p->Lchirld);
qianli(p->Rchirld);
}


int postdpth(struct Bittree *root)
{
int left=0,right=0,max=0;
if(root!=NULL)
{
left=postdpth(root->Lchirld);
right=postdpth(root->Rchirld);
max=left>right?left:right;
return  (max+1);
}
else return 0;






}
void main()  
{  
int m;
struct Bittree *TT;
TT=create();
qianli(TT);
m=postdpth(TT);
printf("%d\n",m);
getchar();
getchar();













8




A
查找


折半查找  
复杂度logn 前提元素按顺序排好


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std;  
#define  ERROR 0
int   search(int *a,int n,int key)


{
int  mid,max,min;
min=0;
max=n;
while(min<=max)
{
mid=(min+max)/2;
if(key>a[mid])
   min=mid+1;
else if (key<a[mid])
   max=mid-1;
else 
   return mid;
}


}




void main()  
{  
    int i;
int h;
    int b[11];
for(i=0;i<11;i++)
scanf("%d",&b[i]);
h=search(b,10,11);
    printf("%d\n",b[h]);
    getchar();
    getchar();
    getchar();
}  






B


二叉排序树


性质:
左子树所有节点的值全部小于他的根节点的值


右子树不为空  右子树所有节点的值大于他的根节点的值


他的左右二叉树也为二叉排序树


//
#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std;  


typedef  struct Bitnode //二叉排序树结构体
{
int data;
struct  Bitnode *lchild,*rchirld;
}Bitnode,*Bitree;


int sec(Bitree T,int key,Bitree f,Bitree *p)//查找
{
if(!T)
{
*p=f;
return 0;
}
else if(key==T->data)
{
*p=T;
return  1;
}
else if(key<T->data)
return sec(T->lchild,key,T,p);
else 
return  sec(T->rchirld,key,T,p);


}


int insert(Bitree *T,int key)//插入
{
Bitree  p,s;
if(!sec(*T,key,NULL, &p))
{
s=(Bitree)malloc(sizeof(Bitnode));
s->data=key;
s->lchild=s->rchirld=NULL;
if(!p)
*T=s;
else if(key<p->data)
p->lchild=s;
else 
p->rchirld=s;
return 1;
}


else  return 0;


}


void main()
{  
  
int i;
int a[10]={62,88,58,47,35,73,51,99,37,93};
Bitree T=NULL;
for(i=0;i<10;i++)
{
insert(&T,a[i]);
}
printf("%d\n",T->lchild->data);
    getchar();
    getchar();
    getchar();


}  

















排序算法




第一种 快速排序


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std; 




typedef struct 
{
int r[10];//r[0]做标兵和临时变量  数组从1开始
int length;


}sqList;






void  swap(sqList *L,int i,int j)
{
int temp=L->r[i];
L->r[i]=L->r[j];
    L->r[j]=temp;


}


int part(sqList *L,int low,int high)
{
int pivotkey;
pivotkey=L->r[low];
while(low<high)
{
while(low<high&&L->r[high]>=pivotkey)
 high--;
swap(L,low,high);
while(low<high&&L->r[low]<=pivotkey)
 low++;
swap(L,low,high);




}
return  low;


}








void sort(sqList *L,int low,int high)
{
int pivot;
if(low<high)
{
pivot=part(L,low,high);
sort(L,low,pivot-1);
sort(L,pivot+1,high);
}
}






void quiksort(sqList *L)
{
sort(L,1,L->length);


}


void main()
{  
sqList p;
p.r[0]=0;
p.r[1]=50;
p.r[2]=10;
p.r[3]=90;
p.r[4]=30;
p.r[5]=70;
p.r[6]=40;
p.r[7]=80;
p.r[8]=60;
p.r[9]=20;
p.length=9;
quiksort(&p);
printf("%d\n",p.r[5]);
getchar();
getchar();



最好复杂度 nlgn  最差就是逆序顺序  N*N  不稳定   辅助空间较大






第二种
插入排序


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std; 




typedef struct 
{
int r[10];//r[0]做标兵和临时变量  数组从1开始
int length;


}sqList;


void  swap(sqList *L,int i,int j)
{
   int temp=L->r[i];
L->r[i]=L->r[j];
    L->r[j]=temp;
}


void insertsort(sqList *L)
{
int i,j;
for(i=2;i<=L->length;i++)
{
if(L->r[i]<L->r[i-1])
{
L->r[0]=L->r[i];
for(j=i-1;L->r[j]>L->r[0];j--)
 L->r[j+1]=L->r[j];
 L->r[j+1]=L->r[0];
}


}






}
void main()
{  
sqList p;
p.r[0]=0;p.r[1]=50;p.r[2]=10;p.r[3]=90;p.r[4]=30;p.r[5]=70;p.r[6]=40;p.r[7]=80;p.r[8]=60;p.r[9]=20;
p.length=9;
insertsort(&p);
printf("%d\n",p.r[5]);
getchar();
getchar();





第三种
简单的选择排序


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std; 




typedef struct 
{
int r[10];//r[0]做标兵和临时变量  数组从1开始
int length;


}sqList;


void  swap(sqList *L,int i,int j)
{
   int temp=L->r[i];
L->r[i]=L->r[j];
    L->r[j]=temp;
}


void select(sqList *L)
{
int i,j,min;
for(i=1;i<L->length;i++)
  {


     min=i;


    for(j=i+1;j<=L->length;j++)
       {
       if(L->r[min]>L->r[j])
            min=j;
       }


if(min!=i)
 swap(L,i,min);


}






}
void main()
{  
sqList p;
p.r[0]=0;p.r[1]=50;p.r[2]=10;p.r[3]=90;p.r[4]=30;p.r[5]=70;p.r[6]=40;p.r[7]=80;p.r[8]=60;p.r[9]=20;
p.length=9;
select(&p);
printf("%d\n",p.r[9]);
getchar();
getchar();





第四种


冒泡排序


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std; 




typedef struct 
{
int r[10];//r[0]做标兵和临时变量  数组从1开始
int length;


}sqList;


void  swap(sqList *L,int i,int j)
{
   int temp=L->r[i];
L->r[i]=L->r[j];
    L->r[j]=temp;
}


void maopao(sqList *L)
{
int i,j,min;
for(i=1;i<L->length;i++)
   {
      for(j=i+1;j<=L->length;j++)
       {
        if(L->r[i]>L->r[j])
            swap(L,i,j);
       }
   }
}






void main()
{  
sqList p;
p.r[0]=0;p.r[1]=50;p.r[2]=10;p.r[3]=90;p.r[4]=30;p.r[5]=70;p.r[6]=40;p.r[7]=80;p.r[8]=60;p.r[9]=20;
p.length=9;
maopao(&p);
printf("%d\n",p.r[4]);
getchar();
getchar();













9 STL容器学习




标准模板库(STL)就是常用的数据结构和算法的集合有了STL,不必再从头写大多的标准数据结构和算法,并且可获得非常高的性能。
泛型程序设计,简单地说就是使用模板的程序设计法,通过模板可以产生类或函数的集合,使它们操作不同的数据类型,从而避免需要为每一种数据类型产生一个单独的类或函数。


1 模板机制


 
模板函数


求两个数最大值,使用模板
template < class T > 

T max(T a , T b){return ( a > b ) ? a , b;
}


template < 模板形参表>


<返回值类型> <函数名>(模板函数形参表)


{
函数定义体
}


#include "stdafx.h"
#include "string.h"
#include <iostream>  
using namespace std;  
#define  ERROR 0;
template <class T>


T  min(T a[],int n)
{
int i;
T minv=a[0];
for(i=0;i<n;i++)
{
  if(minv>a[i])
 minv=a[i];
}


return minv;
}




void main()  
{  


int a[]={1,3,0,2,7,6,4,5,2};
double  b[]={1.2,-3.4,6.8,9,8};
 cout<<"a数组的最小值为:"<<min(a,9)<<endl;
 cout<<"b数组的最小值为:"<<min(b,4)<<endl; 
getchar();
getchar();





优缺点:
克服了C++函数重载用相同函数名字重写几个函数的繁琐
缺点,调试比较困难






2
STL


容器:  可容纳各种数据类型的数据结构。


迭代器:可依次存取容器中元素的东西(当成指针理解)


算法:  用来操作容器中的元素的函数模板。
例如,  STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象。比如,  数组int array[100]就是个容器,而 int * 类型的指针变量就可以作为迭代器,可以为这个容器编写一个排序的算法


容器分为三大类:
 1) 顺序容器 ?
vector:后部插入/删除,直接访问 deque:前/后部插入/删除,直接访问 list:双向链表,任意位置插入/删除
?2)关联容器
set:快速查找,无重复元素 multiset :快速查找,可有重复元素 map:一对一映射,无重复元素,基于关键字查找 multimap :一对一映射,可有重复元素,基于关键字查找
前2者合称为第一类容器 
                
3)容器适配器
stack:LIFO queue:FIFO priority_queue:优先级高的元素先出


1) vector  头文件 <vector>
    实际上就是个动态数组。随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳的性能。
 2) deque   头文件 <deque>
    也是个动态数组,随机存取任何元素都能在常数时间完成(但性能次于vector)。在两端增删元素具有较佳的性能。
 
3) list    头文件 <list> 
    双向链表,在任何位置增删元素都能在常数时间完成。不支持随机存取。
  
   上述三种容器称为顺序容器,是因为元素的插入位置同元素的值无关。


关联式容器内的元素是排序的,插入任何元素,都按相应的排序准则来确定其位置。关联式容器的特点是在查找时具有非常好的性能。
容器适配器简介
1) stack  :头文件 <stack>
栈。是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项。即按照后进先出的原则
2) queue :头文件 <queue>
   队列。插入只可以在尾部进行,删除、检索和修改只允许从头部进行。按照先进先出的原则。
3)priority_queue :头文件 <queue>
优先级队列。最高优先级元素总是第一个出列










A  vector 动态数组


 


#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <vector> //S头文件TL
using namespace std;  
#define  ERROR 0;


void main()  
{  
vector<int>  v1;//动态数组
vector<int>  v2;
     v1.push_back(1);
     v1.push_back(2);
v2.push_back(1); 
v2.push_back(2);
    
cout<<(v1==v2);
 
getchar();
getchar();







用于指向第一类容器中的元素。有const 和非 const两种。
通过迭代器可以读取它指向的元素,通过非const迭代器还能修改其指向的元素。迭代器用法和指针类似。
定义一个容器类的迭代器的方法可以是:
容器类名::iterator   变量名;
或:
容器类名::const_iterator 变量名;
访问一个迭代器指向的元素:
* 迭代器变量名


使用迭代器




#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <vector> //S头文件TL
using namespace std;  
#define  ERROR 0;


void main()  
{  
vector<int>  v1;//动态数组


     v1.push_back(1);
     v1.push_back(2);
v1.push_back(3); 
v1.push_back(4);
vector<int>::const_iterator i;//常量迭代器
for(i=v1.begin(); i!=v1.end(); i++)
       printf("%d\n",*i);//访问一个迭代器指向的元素:* 迭代器变量名
 
vector<int>::reverse_iterator j;//反向迭代器
  for( j = v1.rbegin();j != v1.rend();j++ ) 
cout << *j << ",";getchar();
getchar();





使用算法


#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <algorithm>//算法头文件
#include <vector> //STL 头文件
using namespace std;  
#define  ERROR 0;


void main()  
{  
vector<int>  v1;//动态数组


     v1.push_back(1);
     v1.push_back(2);
v1.push_back(3); 
v1.push_back(4);
vector<int>::iterator p;//常量迭代器
 
     p=find(v1.begin(),v1.end(),3);
 if(p!=v1.end())
  printf("%d\n",*p);


      p=find(v1.begin(),v1.end(),9);
 if(p==v1.end())
  printf("Not find");
getchar();
getchar();





#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <algorithm>//算法头文件
#include <vector> //STL 头文件
using namespace std;  
#define  ERROR 0;


void main()  
{  
int i;
int a[5]={1,2,3,4,5};
 vector<int>  v(5);        //动态数组
cout<<v.end()-v.begin()<<endl;
for(i=0;i< v.size();i++)
v[i]=i;
   v.at(3)=100;
for(i=0;i<v.size();i++)
cout<<v[i]<<endl;
     printf("第二阶段\n");




 vector<int> v2(a,a+5);//构造函数
      v2.insert(v2.begin()+2,30);
     for(i=0;i<v2.size();i++)
  cout<<v2[i]<<endl;
getchar();
getchar();







#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <algorithm>//算法头文件
#include <queue> //STL 头文件
using namespace std;  
#define  ERROR 0;


void main()  
{  


priority_queue<double>  priorities;

priorities.push(3.2);

priorities.push(9.8);

priorities.push(5.4);

while( !priorities.empty() )

{ cout << priorities.top() << " ";    priorities.pop();
}getchar();
getchar();











#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
using namespace std;  
#define  ERROR 0;


void main()  
{  
const int SIZE = 10;
int a1[] = { 2,8,1,50,3,100,8,9,10,2 };  
vector<int> v(a1,a1+SIZE);          //构造函数初始化 容器
ostream_iterator<int> output(cout," ");
vector<int>::iterator location;  //迭代器
location = find(v.begin(),v.end(),10);


if( location != v.end()) {
cout << endl << "1) " << location - v.begin();
}
 
  sort(v.begin(),v.end());//算法
       if( binary_search(v.begin(),v.end(),2)) 
           cout << endl << "2) " << "9 found";
      else
   cout << endl << " 2) " << " 9 not found"; 
getchar();
getchar();









B  queue


deque(读音:deck,意即:double queue,#include<qeque>)容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据:push_front()。此外deque也不支持与vector的capacity()、reserve()类似的操作。


#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
using namespace std;  
#define  ERROR 0;






typedef  deque<int>  INTDEQUE;






void  put_deque(INTDEQUE deque, char *name)  
     { 


      INTDEQUE::iterator pdeque;   //仍然使用迭代器输出  
      cout << "The contents of " << name << " : ";  
      for(pdeque = deque.begin(); pdeque != deque.end(); pdeque++)  
      cout << *pdeque << " "; 
      cout<<endl;  


      }  


    
         
  int main()  
   {  
     
     INTDEQUE deq1;           //deq1对象初始为空  
     INTDEQUE deq2(10,6);     //deq2对象最初有10个值为6的元素    
     INTDEQUE::iterator i;    //声明一个名为i的双向迭代器变量  
     put_deque(deq1,"deq1");  //从前向后显示deq1中的数据
     put_deque(deq2,"deq2");  //从前向后显示deq2中的数据  
     deq1.push_back(2);       //从deq1序列后面添加两个元素  
     deq1.push_back(4);  
     cout<<"deq1.push_back(2) and deq1.push_back(4):"<<endl;  
     put_deque(deq1,"deq1");  
     deq1.push_front(5);       //从deq1序列前面添加两个元素   
     deq1.push_front(7);  
     cout<<"deq1.push_front(5) and deq1.push_front(7):"<<endl;  
     put_deque(deq1,"deq1");  


     printf("第二阶段\n");


       deq1.insert(deq1.begin()+1,3,9);  //添加3个9
       cout<<"deq1.insert(deq1.begin()+1,3,9):"<<endl;  
       put_deque(deq1,"deq1");  
       cout<<"deq1.at(4)="<<deq1.at(4)<<endl; //读第五个位置上的数
       cout<<"deq1[4]="<<deq1[4]<<endl; 


      printf("第三阶段\n");
 
      deq1.pop_front();  
           deq1.pop_back();  
           cout<<"deq1.pop_front() and deq1.pop_back():"<<endl;  
           put_deque(deq1,"deq1"); 


      printf("第四阶段\n");
       
           deq1.erase(deq1.begin()+1);  
           cout<<"deq1.erase(deq1.begin()+1):"<<endl;  
           put_deque(deq1,"deq1");  


     getchar();
getchar();


 }       






C  list


List(#include<list>)又叫链表,是一种双线性列表,只能顺序访问(从前向后或者从后向前),图2是list的数据组织形式。与前面两种容器类有一个明显的区别就是:它不支持随机访问。要访问表中某个下标处的项需要从表头或表尾处(接近该下标的一端)开始循环。而且缺少下标预算符:operator[]




#include "stdafx.h"
#include "string.h"
#include <iostream>  
#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list>
using namespace std;  
#define  ERROR 0;


void PrintIt(list<int> n)  
         {  
           for(list<int>::iterator iter=n.begin(); iter!=n.end(); ++iter)  
           cout<<*iter<<" ";//用迭代器进行输出循环  
          } 
       
  int main()  
   {  
    
      list<int> listn1,listn2;    //给listn1,listn2初始化  
      listn1.push_back(123);  
      listn1.push_back(0);  
      listn1.push_back(34);  
      listn1.push_back(1123);    //now listn1:123,0,34,1123  
      listn2.push_back(100);  
      listn2.push_back(12);    //now listn2:12,100  
      listn1.sort();  
      listn2.sort();    //给listn1和listn2排序  
     PrintIt(listn1);  
      cout<<endl;  
      PrintIt(listn2);  
     cout<<endl; 
         listn1.merge(listn2);    //合并两个排序列表后,listn1:0,12,34,100,123,1123  
      cout<<endl;  
         PrintIt(listn1);  
     getchar();
getchar();


 }       
 







集和多集(set 和multiset 容器类)
一个集合(#include<set>)是一个容器,它其中所包含的元素的值是唯一的。这在收集一个数据的具体值的时候是有用的。集合中的元素按一定的顺序排列,并被作为集合中的实例。如果你需要一个键/值对(pair)来存储数据,map(也是一个关联容器,后面将马上要讲到)是一个更好的选择。一个集合通过一个链表来组织,在插入操作和删除操作上比向量(vector)快,但查找或添加末尾的元素时会有些慢。


集和多集的区别是:set支持唯一键值,set中的值都是特定的,而且只出现一次;而multiset中可以出现副本键,同一值可以出现多次。
#include "stdafx.h"
#include "string.h"
#include <iostream> 


#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list> //STL 头文件
#include <set> //STL 头文件


using namespace std;  
#define  ERROR 0;






int main()  
   {  
    
      set<int>  set1;  
        for(int i=0; i<10; ++i)  
           set1.insert(i);  
   for(set<int>::iterator p=set1.begin();p!=set1.end();++p)  
           cout<<*p<<" "<<endl;  


       if(set1.insert(3).second)//把3插入到set1中   插入成功则set1.insert(3).second返回1,否则返回0  此例中,集中已经有3这个元素了,所以插入将失败 
              cout<<"set insert success"<<endl;  
       else  
              cout<<"set insert failed"<<endl;  


     for(set<int>::iterator g=set1.begin();g!=set1.end();++g)  
           cout<<*g<<" "<<endl;  
       printf("第二阶段\n");
      int a[] = {4, 1, 1, 1, 1, 1, 0, 5, 1, 0};  
      multiset<int>  A;  
      A.insert(set1.begin(),set1.end());  
         for(multiset<int>::iterator q=A.begin();q!=A.end();++q)  
            cout<<*q<<" ";
   cout<<endl;
      A.insert(a,a+10); 
         for(multiset<int>::iterator p=A.begin();p!=A.end();++p)  
            cout<<*p<<" ";  
   cout<<endl;
     getchar();
getchar();


 }       
 




E
映射和多重映射(map 和multimap)
映射和多重映射(#include<map>)基于某一类型Key的键集的存在,提供对T类型的数据进行快速和高效的检索。对map而言,键只是指存储在容器中的某一成员。Map不支持副本键,multimap支持副本键。Map和multimap对象包涵了键和各个键有关的值,键和值的数据类型是不相同的,这与set不同。set中的key和value是Key类型的,而map中的key和value是一个pair结构中的两个分量。Map支持下表运算符operator[],用访问普通数组的方式访问map,不过下标为map的键。在multimap中一个键可以对应多个不同的值。
下面的例程说明了map中键与值的关系。


map


#include "stdafx.h"
#include "string.h"
#include <iostream> 


#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list> //STL 头文件
#include <set> //STL 头文件
#include <map>


using namespace std;  
#define  ERROR 0;






int main()  
   {  
    
      map<char,int,less<char> >   map1;
      map<char,int,less<char> >::iterator  mapIter;
    //char 是键的类型,int是值的类型
    //下面是初始化,与数组类似
    //也可以用map1.insert(map<char,int,less<char> >::value_type(''c'',3));
    map1['c']=3;
    map1['d']=4;
    map1['a']=1;
    map1['b']=2;
    for(mapIter=map1.begin();mapIter!=map1.end();++mapIter)
        cout<<(*mapIter).first<<": "<<(*mapIter).second;
   cout <<endl;


   printf("第二阶段\n");
   
    map<char,int,less<char> >::const_iterator   ptr;   //first对应定义中的char键,second对应定义中的int值  
    ptr=map1.find('d');                                 //检索对应于d键的值是这样做的:
    cout<<" "<<(*ptr).first<<" 键对应于值:"<<(*ptr).second; 


     getchar();
getchar();


 }    










multimap


#include "stdafx.h"
#include "string.h"
#include <iostream> 


#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list> //STL 头文件
#include <set> //STL 头文件
#include <map> //STL 头文件
#include <string>
using namespace std;  
#define  ERROR 0;






int main()  
   {  
   


      multimap<string,string,less<string>>  mulmap;  
      multimap<string,string,less<string>>::iterator   p; 


     //初始化多重映射mulmap:  
      typedef multimap<string,string,less<string> >::value_type vt;  
      typedef string s;  


       mulmap.insert(vt(s("Tom "),s("is a student")));  
       mulmap.insert(vt(s("Tom "),s("is a boy")));  
       mulmap.insert(vt(s("Tom "),s("is a bad boy of blue!")));  
       mulmap.insert(vt(s("Jerry "),s("is a student")));  
       mulmap.insert(vt(s("Jerry "),s("is a beatutiful girl")));  
       mulmap.insert(vt(s("DJ "),s("is a student")));  


      //输出初始化以后的多重映射mulmap:  
      for(p=mulmap.begin();p!=mulmap.end();++p)  
         cout<<(*p).first<<(*p).second<<endl;  
      printf("第二阶段\n");
    
     cout<<"find Jerry :"<<endl;  
     p=mulmap.find(s("Jerry "));  
     while((*p).first=="Jerry ")  
          {  
              cout<<(*p).first<<(*p).second<<endl;  
             ++p;  
          }     


  








     getchar();
getchar();


 }       
 
基本算法


#include "stdafx.h"
#include "string.h"
#include <iostream> 


#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list> //STL 头文件
#include <set> //STL 头文件
#include <map> //STL 头文件
#include <string>
using namespace std;  
#define  ERROR 0;






int main()  
   {  
   


       int a[10]={12,0,5,3,6,8,9,34,32,18};  
        int b[5]={5,3,6,8,9};  
        int d[15];  
        sort(a,a+10);  
           for(int i=0;i<10;i++)  
               cout<<" "<<a[i];  
          cout<<endl;
   sort(b,b+5); 
      for(int i=0;i<5;i++)  
                cout<<" "<<b[i]; 
       cout<<endl;
      if(includes(a,a+10,b,b+5))  
         cout<<"sorted b members are included in a."<<endl;  
      else  
          cout<<"sorted a dosn`t contain sorted b!"<<endl;  
       merge(a,a+10,b,b+5,d);  
       for(int j=0;j<15;j++)  
           cout<<" "<<d[j];  
           cout<<endl;




         getchar();
getchar();


 }   








#include "stdafx.h"
#include "string.h"
#include <iostream> 
#include <string>
#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list> //STL 头文件
#include <set> //STL 头文件
#include <map> //STL 头文件
#include <iterator>  //STL 头文件
using namespace std;  
#define  ERROR 0;






int main()  
   {  
   
      int arr[6]={1,12,3,2,1215,90};  
      int arr1[6];  
      int arr2[6]={2,5,6,9,0,-56};  
      copy(arr,(arr+6),arr1);//将数组aar复制到arr1  
      cout<<"arr[6] copy to arr1[7],now arr1: "<<endl;  
      for(int i=0;i<6;i++)  
      cout<<" "<<arr1[i];  


       cout<<endl;
      reverse(arr,arr+6);//将排好序的arr翻转  
      cout<<"arr reversed ,now arr:"<<endl;  
      copy(arr,arr+6,ostream_iterator<int>(cout, " "));//复制到输出迭代器  


    


      swap_ranges(arr,arr+6,arr2);//交换arr和arr2序列 


      cout<<"arr swaped to arr2,now arr:"<<endl;  
      copy(arr,arr+6,ostream_iterator<int>(cout, " "));  
      cout<<"arr2:"<<endl;  
      copy(arr2,arr2+6,ostream_iterator<int>(cout, " "));  


     getchar();
getchar();


 }       
 




#include "stdafx.h"
#include "string.h"
#include <iostream> 
#include <string>
#include <algorithm>//算法头文件
#include <queue> //STL 头文件
#include  <vector>//STL 头文件
#include <list> //STL 头文件
#include <set> //STL 头文件
#include <map> //STL 头文件
#include <iterator>  //STL 头文件
using namespace std;  
#define  ERROR 0;






int main()  
   {  
        int a[10]={12,31,5,2,23,121,0,89,34,66};  
        vector<int> v1(a,a+10); //构造函数
        vector<int>::iterator result1,result2;//result1和result2是随机访问迭代器


      result1=find(v1.begin(),v1.end(),2);   //在v1中找到2,result1指向v1中的2  
      result2=find(v1.begin(),v1.end(),8);      //在v1中没有找到8,result2指向的是v1.end()  
      cout<<result1-v1.begin()<<endl; //3-0=3或4-1=3,屏幕结果是3  
      cout<<result2-v1.end()<<endl;  //结果为0 


        int b[9]={5,2,23,54,5,5,5,2,2};  
        vector<int> v2(a+2,a+8);  
        vector<int> v3(b,b+4);  


        result1=search(v1.begin(),v1.end(),v2.begin(),v2.end());     //在v1中找到了序列v2,result1指向v2在v1中开始的位置  
        cout<<*result1<<endl;  
        result1=search(v1.begin(),v1.end(),v3.begin(),v3.end());  
        cout<<*(result1-1)<<endl;  //在v1中没有找到序列v3,result指向v1.end(),屏幕打印出v1的最后一个元素66 
            
        vector<int> v4(b,b+9);  
        int i=count(v4.begin(),v4.end(),5);  //计算v4中有几个5
        int j=count(v4.begin(),v4.end(),2);  //计算v4中有几个2 
        cout<<"there are "<<i<<" members in v4 equel to 5"<<endl;  
        cout<<"there are "<<j<<" members in v4 equel to 2"<<endl;  
        getchar();
   getchar();


 }       
 


总结:


高效的随机存取  不在乎插入和删除的效率  使用vector
要大量的插入和删除  不在乎随机存取  则应使用list
要随机存取  并且关心两端数据的插入和删除  则应使用 deque








10

























































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值