1. 程式人生 > 實用技巧 >java volatile 實現變數可見性

java volatile 實現變數可見性

1.順序表的定義

順序表是線性表的順序表示,即用一組地址連續的儲存單元依次儲存線性表的資料元素。

2.順序表的儲存結構

為了使順序表的空間分配儘可能不受限制,這裡先讓順序表的初始化容量為8,當空間不足時再對容量進行擴充套件,每次容量的增量為3。

#define SEQLIST_INIT_SIZE 8  //初始化大小
#define INC_SIZE          3  //空間的增量

typedef int ElemType;        //元素型別

typedef struct SeqList
{
    ElemType *base;          //指向順序表開闢的基準空間
    int
capacity; //容量 int size; //表的長度(大小) }SeqList;

3.順序表的常用操作

1.初始化

//順序表的初始化
void InitSeqList(SeqList *list)
{
    list->base = (ElemType *)malloc(sizeof(ElemType) * SEQLIST_INIT_SIZE);
    assert(list->base != NULL);
    list->capacity = SEQLIST_INIT_SIZE;
    list->size = 0
; }

2.容量擴充套件

//空間不足,重新開闢
bool Inc(SeqList *list)
{
    ElemType *newbase = (ElemType*)realloc(list->base,sizeof(ElemType)*(list->capacity+INC_SIZE));
    //空間開闢是否失敗?
    if(newbase == NULL)
    {
        printf("增配空間失敗,記憶體不足.\n");
        return false;
    }
    list->base = newbase;
    list
->capacity += INC_SIZE; return true; }

3.尾插

//在順序表尾部插入資料
void push_back(SeqList *list, ElemType x)
{
    //判斷順序表空間是否滿且增加空間是否失敗?
    if(list->size >= list->capacity && !Inc(list))
    {
        printf("順序表空間已滿,%d不能尾部插入資料.\n",x);
        return;
    }
    //資料尾插
    list->base[list->size] = x; //size的大小就是尾部插入時陣列的下標
    list->size++;
}

4.頭插

//在順序表頭部插入資料
void push_front(SeqList *list, ElemType x)
{
    //判斷順序表空間是否滿且增加空間是否失敗?
    if(list->size >= list->capacity && !Inc(list))
    {
        printf("順序表空間已滿,%d不能頭部插入資料.\n",x);
        return;
    }
    //將順序表資料後移
    for(int i=list->size; i>0; --i)
    {
        list->base[i] = list->base[i-1];
    }
    //資料頭插
    list->base[0] = x;
    list->size++;
}

5.儲存資料顯示

//顯示順序表內的資料
void show_list(SeqList *list)
{
    for(int i=0; i<list->size; ++i)
    {
        printf("%d ",list->base[i]);
    }
    printf("\n");
}

6.尾刪

//刪除順序表尾部資料
void pop_back(SeqList *list)
{
    //判斷順序表是否為空?
    if(list->size == 0)
    {
        printf("順序表已空,不能尾部刪除資料.\n");
        return;
    }
    //將size值減1,來達到刪除的目的
    list->size--;
}

7.頭刪

//刪除順序表頭部資料
void pop_front(SeqList *list)
{
    //判斷表是否為空?
    if(list->size == 0)
    {
        printf("順序表已空,不能尾部刪除資料.\n");
        return;
    }
    //將順序表中的資料前移一位(第一個資料除外)
    for(int i=0; i<list->size-1; ++i)
    {
        list->base[i] = list->base[i+1];
    }
    //將size值減1,來達到刪除的目的
    list->size--;
}

8.按位置插入資料

//按位置插入資料
void insert_pos(SeqList *list, int pos, ElemType x)
{
    //判斷位置是否合法?
    if(pos<0 || pos>list->size)
    {
        printf("插入資料的位置非法,不能插入資料.\n");
        return;
    }
    
    //判斷順序表空間是否滿且增加空間是否失敗?
    if(list->size >= list->capacity && !Inc(list))
    {
        printf("順序表空間已滿,%d不能按位置插入資料.\n",x);
        return;
    }
    
    //將該位置及其之後的資料都向後移動一位
    for(int i=list->size; i>pos; --i)
    {
        list->base[i] = list->base[i-1];
    }
    //將資料插入
    list->base[pos] = x;
    list->size++;
}

9.查詢資料

假定順序表內的資料唯一。

//查詢資料
int find(SeqList *list, ElemType key)
{
    //遍歷順序表,查詢資料
    for(int i=0; i<list->size; ++i)
    {
        if(list->base[i] == key)
            return i;  //找到資料返回
    }
    return -1;
}

10.求順序表長度

//求順序表的長度
int length(SeqList *list)
{
    return list->size;
}

11.按位置刪除資料

//按位置刪除資料
void delete_pos(SeqList *list, int pos)
{
    //判斷位置是否合法?
    if(pos<0 || pos>=list->size)
    {
        printf("刪除資料的位置非法,不能刪除資料.\n");
        return;
    }
    //將該位置之後的資料都向前移動一位
    for(int i=pos; i<list->size-1; ++i)
    {
        list->base[i] = list->base[i+1];
    }
    list->size--;
}

12.按值刪除資料

//按值刪除
void delete_val(SeqList *list, ElemType key)
{
    //查詢值所在的位置
    int pos = find(list,key);
    //順序表中是否存在該值?
    if(pos == -1)
    {
        printf("要刪除的資料不存在.\n");
        return;
    }
    //存在該值就刪除
    delete_pos(list,pos);
}

13.排序

//順序表的排序(氣泡排序 )
void sort(SeqList *list)
{
    //氣泡排序,每趟比較可以確定一個最大(最小)的數,所以需要size-1趟(最後一次自己跟自己比較不需要)
    for(int i=0; i<list->size-1; ++i) 
    {
        //每趟中需要比較size-i-1次(前面比較完的i個數不需要重複比較,最後一次自己跟自己比較不需要)
        for(int j=0; j<list->size-i-1; ++j) 
        {
            if(list->base[j] > list->base[j+1])
            {
                ElemType tmp = list->base[j];
                list->base[j] = list->base[j+1];
                list->base[j+1] = tmp;
            }
        }
    }
}

14.逆置

//順序表的逆置
void resver(SeqList *list)
{
    //判斷是否需要進行逆置操作
    if(list->size==0 || list->size==1)
        return;
    //low低位指標,指向低位
    int low = 0;
    //hight高位指標,指向高位
    int high = list->size-1;
    //臨時空間
    ElemType tmp;
    //當低位指標所指位置小於高位指標指向位置時,進行資料交換
    while(low < high)
    {
        tmp = list->base[low];
        list->base[low] = list->base[high];
        list->base[high] = tmp;

        low++;
        high--;
    }
}

15.清空順序表

//清空順序表
void clear(SeqList *list)
{
    list->size = 0;
}

16.銷燬順序表

//銷燬順序表
void destroy(SeqList *list)
{
    free(list->base);
    list->base = NULL;
    list->capacity = 0;
    list->size = 0;
}

4.擴充套件

將兩個從小到大排序的有序表按照由小到大的順序合併到另一個有序表中。

//將兩個從小到大排序的有序表按照由小到大的順序合併到另一個有序表中
void merge(SeqList *lt, SeqList *la, SeqList *lb)
{
    //構造存放有序表la和lb的有序表lt
    lt->capacity = la->size + lb->size;
    lt->base = (ElemType*)malloc(sizeof(ElemType)*lt->capacity);
    assert(lt->base != NULL);

    int ia = 0;
    int ib = 0;
    int ic = 0;
    //當有序表la和lb中的元素都還沒比較完時,將它們相應下標下的元素進行比較,並將小的元素放入lt
    while(ia<la->size && ib<lb->size)
    {
        if(la->base[ia] < lb->base[ib])
            lt->base[ic++] = la->base[ia++];
        else
            lt->base[ic++] = lb->base[ib++];
    }
    //當只有有序表la中有元素時,將la中的剩餘元素逐一放入lt
    while(ia < la->size)
    {
        lt->base[ic++] = la->base[ia++];
    }
    //當只有有序表lb中有元素時,將lb中的剩餘元素逐一放入lt
    while(ib < lb->size)
    {
        lt->base[ic++] = lb->base[ib++];
    }
    //更新有序表lt的長度
    lt->size = la->size + lb->size;
}

5.附錄

Main.cpp

#include"SeqList.h"


//順序表常用操作測試
void main()
{
    SeqList mylist;
    InitSeqList(&mylist);

    ElemType Item;
    int pos;
    int select = 1;
    while(select)
    {
        printf("**************************************\n");
        printf("* [1]  push_back    [2]  push_fornt  *\n");
        printf("* [3]  show_list    [4]  pop_back    *\n");
        printf("* [5]  pop_front    [6]  insert_pos  *\n");
        printf("* [7]  find         [8]  lenght      *\n");
        printf("* [9]  delete_pos   [10]  delete_val *\n");
        printf("* [11] sort         [12]  resver     *\n");
        printf("* [13] clear        [14*]  destroy   *\n");
        printf("* [0]  quit_system                   *\n");
        printf("**************************************\n");
        printf("請選擇:>");
        scanf("%d",&select);
        if(select == 0)
            break;

        switch(select)
        {
        case 1:
            printf("請輸入要插入的資料(-1結束):>");
            while(scanf("%d",&Item),Item!=-1)
            {
                push_back(&mylist,Item);
            }
            break;
        case 2:
            printf("請輸入要插入的資料(-1結束):>");
            while(scanf("%d",&Item),Item!=-1)
            {
                push_front(&mylist,Item);
            }
            break;
        case 3:
            show_list(&mylist);
            break;
        case 4:
            pop_back(&mylist);
            break;
        case 5:
            pop_front(&mylist);
            break;
        case 6:
            printf("請輸入要插入資料:>");
            scanf("%d",&Item);
            printf("請輸入要插入的位置:>");
            scanf("%d",&pos);
            insert_pos(&mylist,pos,Item);
            break;
        case 7:
            printf("請輸入要查詢的資料:>");
            scanf("%d",&Item);
            pos = find(&mylist,Item);
            if(pos == -1)
                printf("查詢的資料%d在順序表中不存在.\n",Item);
            else
                printf("查詢的資料%d在順序表中的%d下標位置.\n",Item,pos);
            break;
        case 8:
            printf("順序表的長度為:> %d\n",length(&mylist));
            break;
        case 9:
            printf("請輸入要刪除資料的位置:>");
            scanf("%d",&pos);
            delete_pos(&mylist,pos);
            break;
        case 10:
            printf("請輸入要刪除的資料:>");
            scanf("%d",&Item);
            delete_val(&mylist,Item);
            break;
        case 11:
            sort(&mylist);
            break;
        case 12:
            resver(&mylist);
            break;
        case 13:
            clear(&mylist);
            break;
        //case 14:
            //destroy(&mylist);
        //    break;
        default:
            printf("輸入的選擇錯誤,請重新輸入.\n");
            break;
        }
    }
    destroy(&mylist);
}


/*
//擴充套件測試
void main()
{
    SeqList mylist,youlist,list;
    InitSeqList(&mylist);
    InitSeqList(&youlist);

    push_back(&mylist,1);
    push_back(&mylist,3);
    push_back(&mylist,5);
    push_back(&mylist,7);
    push_back(&mylist,9);

    push_back(&youlist,2);
    push_back(&youlist,4);
    //push_back(&youlist,6);
    push_back(&youlist,8);
    //push_back(&youlist,10);

    merge(&list,&mylist,&youlist);
    show_list(&list);
}
*/
View Code

SeqList.h

#ifndef __SEQLIST_H__
#define __SEQLIST_H__

#include<stdio.h>
#include<malloc.h>
#include<assert.h>

#define SEQLIST_INIT_SIZE 8  //初始化大小
#define INC_SIZE          3  //空間的增量

typedef int ElemType;        //元素型別

typedef struct SeqList
{
    ElemType *base;          //指向順序表開闢的基準空間
    int       capacity;     //容量 
    int       size;         //表的長度(大小)
}SeqList;

bool Inc(SeqList *list);
void InitSeqList(SeqList *list);
void push_back(SeqList *list, ElemType x);
void push_front(SeqList *list, ElemType x);
void show_list(SeqList *list);

void pop_back(SeqList *list);
void pop_front(SeqList *list);
void insert_pos(SeqList *list, int pos, ElemType x);
int  find(SeqList *list, ElemType key);
int length(SeqList *list);

void delete_pos(SeqList *list, int pos);
void delete_val(SeqList *list, ElemType key);

void sort(SeqList *list);
void resver(SeqList *list);
void clear(SeqList *list);
void destroy(SeqList *list);

void merge(SeqList *lt, SeqList *la, SeqList *lb);

#endif //__SEQLIST_H__
View Code

SeqList.cpp

#include"SeqList.h"

//空間不足,重新開闢
bool Inc(SeqList *list)
{
    ElemType *newbase = (ElemType*)realloc(list->base,sizeof(ElemType)*(list->capacity+INC_SIZE));
    //空間開闢是否失敗?
    if(newbase == NULL)
    {
        printf("增配空間失敗,記憶體不足.\n");
        return false;
    }
    list->base = newbase;
    list->capacity += INC_SIZE;
    return true;
}

//順序表的初始化
void InitSeqList(SeqList *list)
{
    list->base = (ElemType *)malloc(sizeof(ElemType) * SEQLIST_INIT_SIZE);
    assert(list->base != NULL);
    list->capacity = SEQLIST_INIT_SIZE;
    list->size = 0;
}

//在順序表尾部插入資料
void push_back(SeqList *list, ElemType x)
{
    //判斷順序表空間是否滿且增加空間是否失敗?
    if(list->size >= list->capacity && !Inc(list))
    {
        printf("順序表空間已滿,%d不能尾部插入資料.\n",x);
        return;
    }
    //資料尾插
    list->base[list->size] = x; //size的大小就是尾部插入時陣列的下標
    list->size++;
}

//在順序表頭部插入資料
void push_front(SeqList *list, ElemType x)
{
    //判斷順序表空間是否滿且增加空間是否失敗?
    if(list->size >= list->capacity && !Inc(list))
    {
        printf("順序表空間已滿,%d不能頭部插入資料.\n",x);
        return;
    }
    //將順序表資料後移
    for(int i=list->size; i>0; --i)
    {
        list->base[i] = list->base[i-1];
    }
    //資料頭插
    list->base[0] = x;
    list->size++;
}

//顯示順序表內的資料
void show_list(SeqList *list)
{
    for(int i=0; i<list->size; ++i)
    {
        printf("%d ",list->base[i]);
    }
    printf("\n");
}

//刪除順序表尾部資料
void pop_back(SeqList *list)
{
    //判斷順序表是否為空?
    if(list->size == 0)
    {
        printf("順序表已空,不能尾部刪除資料.\n");
        return;
    }
    //將size值減1,來達到刪除的目的
    list->size--;
}

//刪除順序表頭部資料
void pop_front(SeqList *list)
{
    //判斷表是否為空?
    if(list->size == 0)
    {
        printf("順序表已空,不能尾部刪除資料.\n");
        return;
    }
    //將順序表中的資料前移一位(第一個資料除外)
    for(int i=0; i<list->size-1; ++i)
    {
        list->base[i] = list->base[i+1];
    }
    //將size值減1,來達到刪除的目的
    list->size--;
}

//按位置插入資料
void insert_pos(SeqList *list, int pos, ElemType x)
{
    //判斷位置是否合法?
    if(pos<0 || pos>list->size)
    {
        printf("插入資料的位置非法,不能插入資料.\n");
        return;
    }
    
    //判斷順序表空間是否滿且增加空間是否失敗?
    if(list->size >= list->capacity && !Inc(list))
    {
        printf("順序表空間已滿,%d不能按位置插入資料.\n",x);
        return;
    }
    
    //將該位置及其之後的資料都向後移動一位
    for(int i=list->size; i>pos; --i)
    {
        list->base[i] = list->base[i-1];
    }
    //將資料插入
    list->base[pos] = x;
    list->size++;
}

//查詢資料
int find(SeqList *list, ElemType key)
{
    //遍歷順序表,查詢資料
    for(int i=0; i<list->size; ++i)
    {
        if(list->base[i] == key)
            return i;  //找到資料返回
    }
    return -1;
}

//求順序表的長度
int length(SeqList *list)
{
    return list->size;
}

//按位置刪除資料
void delete_pos(SeqList *list, int pos)
{
    //判斷位置是否合法?
    if(pos<0 || pos>=list->size)
    {
        printf("刪除資料的位置非法,不能刪除資料.\n");
        return;
    }
    //將該位置之後的資料都向前移動一位
    for(int i=pos; i<list->size-1; ++i)
    {
        list->base[i] = list->base[i+1];
    }
    list->size--;
}
//按值刪除
void delete_val(SeqList *list, ElemType key)
{
    //查詢值所在的位置
    int pos = find(list,key);
    //順序表中是否存在該值?
    if(pos == -1)
    {
        printf("要刪除的資料不存在.\n");
        return;
    }
    //存在該值就刪除
    delete_pos(list,pos);
}

//順序表的排序(氣泡排序 )
void sort(SeqList *list)
{
    //氣泡排序,每趟比較可以確定一個最大(最小)的數,所以需要size-1趟(最後一次自己跟自己比較不需要)
    for(int i=0; i<list->size-1; ++i) 
    {
        //每趟中需要比較size-i-1次(前面比較完的i個數不需要重複比較,最後一次自己跟自己比較不需要)
        for(int j=0; j<list->size-i-1; ++j) 
        {
            if(list->base[j] > list->base[j+1])
            {
                ElemType tmp = list->base[j];
                list->base[j] = list->base[j+1];
                list->base[j+1] = tmp;
            }
        }
    }
}

//順序表的逆置
void resver(SeqList *list)
{
    //判斷是否需要進行逆置操作
    if(list->size==0 || list->size==1)
        return;
    //low低位指標,指向低位
    int low = 0;
    //hight高位指標,指向高位
    int high = list->size-1;
    //臨時空間
    ElemType tmp;
    //當低位指標所指位置小於高位指標指向位置時,進行資料交換
    while(low < high)
    {
        tmp = list->base[low];
        list->base[low] = list->base[high];
        list->base[high] = tmp;

        low++;
        high--;
    }
}

//清空順序表
void clear(SeqList *list)
{
    list->size = 0;
}

//銷燬順序表
void destroy(SeqList *list)
{
    free(list->base);
    list->base = NULL;
    list->capacity = 0;
    list->size = 0;
}

//將兩個從小到大排序的有序表按照由小到大的順序合併到另一個有序表中
void merge(SeqList *lt, SeqList *la, SeqList *lb)
{
    //構造存放有序表la和lb的有序表lt
    lt->capacity = la->size + lb->size;
    lt->base = (ElemType*)malloc(sizeof(ElemType)*lt->capacity);
    assert(lt->base != NULL);

    int ia = 0;
    int ib = 0;
    int ic = 0;
    //當有序表la和lb中的元素都還沒比較完時,將它們相應下標下的元素進行比較,並將小的元素放入lt
    while(ia<la->size && ib<lb->size)
    {
        if(la->base[ia] < lb->base[ib])
            lt->base[ic++] = la->base[ia++];
        else
            lt->base[ic++] = lb->base[ib++];
    }
    //當只有有序表la中有元素時,將la中的剩餘元素逐一放入lt
    while(ia < la->size)
    {
        lt->base[ic++] = la->base[ia++];
    }
    //當只有有序表lb中有元素時,將lb中的剩餘元素逐一放入lt
    while(ib < lb->size)
    {
        lt->base[ic++] = lb->base[ib++];
    }
    //更新有序表lt的長度
    lt->size = la->size + lb->size;
}
View Code