Example #1
0
/* Splits a list into two halves to be merged */
static struct list *list_merge_sort(struct list *left, unsigned int len, comparison_fn_t comparison_fn)
{
	struct list *right = NULL;
	unsigned int left_len = len / 2;
	unsigned int right_len = len / 2 + len % 2;
	unsigned int i;

	if (!left) {
		return NULL;
	}

	if (len == 1) {
		return left;
	}

	right = left;

	/* Split into left and right lists */
	for (i = 0; i < left_len; i++) {
		right = right->next;
	}
	right->prev->next = NULL;
	right->prev = NULL;

	/* Recurse */
	left = list_merge_sort(left, left_len, comparison_fn);
	right = list_merge_sort(right, right_len, comparison_fn);
	return list_merge(left, right, comparison_fn);
}
Example #2
0
/* e.g. void list_merge(node** head){ left = *head; *head = NULL; ... continue in the same manner but don't return */
node* list_merge_sort(node* left){

    /* one element by itself is sorted */
    if(!left->next){
        return left;
    }
    node *middle = left, *end = left;
    /* find a suitable middle node at which to split */
    while(end){
        end = end->next;
        middle = middle->next;
        if(end){
            end = end->next;
        }
    }
    /* break the list up */
    node *right;
    if(middle->next != end){
        right = middle->next;
        middle->next = NULL;
    }else{
        right = left->next;
        left->next = NULL;
    }

    /* call recursively on halves */
    left = list_merge_sort(left);
    right = list_merge_sort(right);

    /* put back together in order */
    /* the first element of the list will change we need to track what that is and return it */
    node *head = NULL, *pos = NULL;

    while(left || right){
        /* check if we can use from left */
        node* use = NULL;
        if(!right || (left && left->data <= right->data)){
            use = left;
            left = left->next;
        }
        /* else use right as next */
        else{
            use = right;
            right = right->next;
        }
        /* the head is the first node used */
        if(!head){
            pos = head = use;
        }
        /* set the next node in the new list to use and move position to that */
            pos->next = use;
            pos = use;
    }
    return head;
}
Example #3
0
int main(int argc,char *argv[],char *env[])
{
	list_t *plist = NULL;

	plist = list_create();

//	srand(getpid());
	int i;
	for(i = 0;i < 300000;i++)
	{
		int *ptmp = malloc(sizeof(int));
		*ptmp = rand();
		list_push_head(plist,ptmp);
	}

//	list_traverse(plist, print);
//	putchar('\n');

//	list_insert_sort(plist, cmp);

	list_merge_sort(plist, cmp);

	if(list_issort(plist, cmp) == SUCCESS)
		printf("issort.\n");

	list_destroy(plist,free_data);

	return 0;
}
char *test_merge_sort()
{
    list_t *words = create_words();

    // should work on a list that needs sorting
    list_t *res = list_merge_sort(words, (list_compare)strcmp);
    mu_assert(is_sorted(res), "Words are not sorted after merge sort.");

    list_t *res2 = list_merge_sort(res, (list_compare)strcmp);
    mu_assert(is_sorted(res2), "Should still be sorted after merge sort.");

    list_destroy(&res2);
    list_destroy(&res);

    list_destroy(&words);

    return NULL;
}
Example #5
0
List * list_merge_sort(List *list, int size, List_Compare_Cb compare) {
    List *right, *left, *result;
    int i;

    if (size <= 1)
        return list;

    // Split the list into two halves
    left = list;
    right = list;
    for (i = 0; i < size/2; i++)
        right = right->next;

    right->prev->next = NULL;
    right->prev = NULL;

    // Sort the halves separately
    left = list_merge_sort(left, size/2, compare);
    right = list_merge_sort(right, (size+1)/2, compare);

    // Merge the sorted halves
    return list_sorted_merge(left, right, compare);
}
Example #6
0
File: sort1.c Project: hoelzl/Clicc
void sort1(CL_FORM *base)
{
	if(CL_LISTP(ARG(0)))
	{
		list_merge_sort(ARG(0));
	}
	else
	{
		COPY(ARG(0), ARG(3));
		LOAD_FIXNUM(ARG(4), 0, ARG(4));
		COPY(ARG(0), ARG(5));
		Flength(ARG(5));
		COPY(ARG(1), ARG(6));
		COPY(ARG(2), ARG(7));
		quick_sort(ARG(3));
		COPY(ARG(3), ARG(0));
	}
}
Example #7
0
struct list *list_sort(struct list *list, comparison_fn_t comparison_fn)
{
	list = list_head(list);
	unsigned int len = list_len(list);
	return list_merge_sort(list, len, comparison_fn);
}
Example #8
0
List * list_sort(List *list, List_Compare_Cb compare) {
    return list_merge_sort(list, list_count(list), compare);
}
Example #9
0
int main(int argc, char** argv){
    node* list = filetolist(argv[1]);
    list = list_merge_sort(list);
    list_print(list);
}
Example #10
0
int
run_access (newts_nfref *ref)
{
  List access_list;
  short changed = FALSE;
  short redraw = TRUE;
  int c;
  int first = 0;
  int entries;

  entries = get_access_list (ref, &access_list);

  while (1)
    {
      if (redraw)
        display_access (&access_list, first, entries);
      redraw = FALSE;

      mvprintw (LINES - 2, 0, _("Option: "));
      refresh ();

      c = getch ();

      switch (c)
        {
        case '?':
          access_help ();
          /* Fall through. */

        case 'r':  /* Redraw the screen. */
        case '\f':
          redraw = TRUE;
          break;

        case '!':
          redraw = TRUE;
          spawn_subshell ();
          break;

        case 's':
          move (LINES - 2, 0);
          clrtoeol ();
          printw (_("Sorting..."));
          refresh ();
          list_merge_sort (&access_list);
          redraw = TRUE;
          break;

        case 'Q':  /* Quit without saving. */
        case 'K':
          list_destroy (&access_list);
          return 0;

        case 'q':
        case 'k':
          if (changed)
            {
              list_merge_sort (&access_list);
              write_access_list (ref, &access_list);
            }
          list_destroy (&access_list);
          return 0;

        case '-':
        case KEY_UP:
        case KEY_PPAGE:
          first -= c == KEY_UP ? 1 : (LINES - 6) / 2 - 1;
          if (first < 0)
            first = 0;
          redraw = TRUE;
          break;

        case '+':
        case KEY_DOWN:
        case KEY_NPAGE:
          first += c == KEY_DOWN ? 1 : (LINES - 6) / 2 - 1;
          if (first >= entries - (LINES - 6) / 2)
            {
              first = entries - (LINES - 6) - 3;
              if (first < 0)
                first = 0;
            }
          redraw = TRUE;
          break;

        case 'i':  /* Insert new entries. */
          {
            char *persistent_error = NULL;
            short stop = FALSE;

            while (entries < NPERMS && !stop)
              {
                ListNode *node;
                struct access *access_entry;
                char *temp, *name, *prompt;
                int key, i;
                int y, x;
                enum newts_access_scopes scope;
                int scope_is_set = FALSE;
                int mode;
                short restart = FALSE;
                short advice_displayed = FALSE;

                if (traditional)
                  mvprintw (LINES - 5, 39, _("Entry type: "));
                else
                  {
                    clear ();
                    display_access (&access_list, first, entries);
                    if (persistent_error != NULL)
                      {
                        move (LINES - 3, 0);
                        clrtoeol ();
                        printw ("%s", persistent_error);
                        persistent_error = NULL;
                      }
                    move (LINES - 2, 0);
                    clrtoeol ();
                    printw (_("Entry type: "));
                  }
                refresh ();
                if (!traditional)
                  advice_displayed = FALSE;
                getyx (stdscr, y, x);
                while (scope_is_set == FALSE)
                  {
                    key = getch ();
                    if (key == '\n' || key == '\r' || key == KEY_ENTER ||
                        key == 'q' || key == 'k')
                      {
                        if (traditional && (key == 'k' || key == 'q'))
                          echochar (key);
                        stop = TRUE;
                        break;
                      }

                    switch (key)
                      {
                      case 'u':
                        if (traditional)
                          {
                            echochar (key);
                            move (y, x);
                          }
                        scope = SCOPE_USER;
                        scope_is_set = TRUE;
                        break;

                      case 'g':
                        if (traditional)
                          {
                            echochar (key);
                            move (y, x);
                          }
                        scope = SCOPE_GROUP;
                        scope_is_set = TRUE;
                        break;

                      case 's':
                        if (traditional)
                          {
                            echochar (key);
                            move (y, x);
                          }
                        scope = SCOPE_SYSTEM;
                        scope_is_set = TRUE;
                        break;

                      case KEY_RESIZE:
                        break;

                      case EOF:
                        clear ();
                        display_access (&access_list, first, entries);
                        if (traditional)
                          {
                            if (advice_displayed)
                              mvprintw (LINES - 5, 54, "(u,g,s, q,k,<cr>)");
                            move (LINES - 5, 51);
                          }
                        else
                          {
                            if (advice_displayed)
                              mvprintw (LINES - 3, 0,
                                        _("Please enter 'u', 'g', or 's'; or "
                                          "'q', 'k', or <RET> to exit."));
                            mvprintw (LINES - 2, 0, _("Entry type: "));
                          }
                        refresh ();
                        break;

                      default:
                        advice_displayed = TRUE;
                        if (traditional)
                          {
                            mvprintw (LINES - 5, 54, "(u,g,s, q,k,<cr>)");
                            move (LINES - 5, 51);
                          }
                        else
                          {
                            move (LINES - 3, 0);
                            clrtoeol ();
                            printw (_("Please enter 'u', 'g', or 's'; or 'q', "
                                      "'k', or <RET> to exit."));
                            move (LINES - 2, 0);
                            clrtoeol ();
                            printw (_("Entry type: "));
                          }
                        refresh ();
                        break;
                      }
                  }

                if (stop) continue;

                if (traditional)
                  {
                    prompt = newts_nmalloc (strlen (_("Name: ")) + 40,
                                            sizeof (char));
                    strcpy (prompt, "                                       ");
                    strncat (prompt, _("Name: "),
                             strlen (_("Name: ")) + 1);
                    move (LINES - 4, 0);
                    clrtoeol ();
                  }
                else
                  {
                    move (LINES - 3, 0);
                    clrtoeol ();
                    prompt = newts_strdup (scope == SCOPE_SYSTEM ? _("System name: ") :
                                           scope == SCOPE_GROUP ? _("Group name: ") :
                                           _("User name: "));
                    move (LINES - 2, 0);
                    clrtoeol ();
                  }
                refresh ();
                temp = gl_getline (prompt);
                temp[strlen (temp) - 1] = '\0';
                newts_free (prompt);

                if (strlen (temp) == 0)
                  continue;
                name = newts_strdup (temp);
                gl_histadd (name);

                if (scope == SCOPE_USER)
                  {
                    if (strcasecmp (name, "other") != 0)
                      {
                        struct passwd *pw = getpwnam (name);

                        if (pw == NULL)
                          {
                            if (traditional)
                              {
                                move (LINES - 3, 0);
                                clrtoeol ();
                                mvprintw (LINES - 3, 39, _("--No such user--"));
                              }
                            else
                              persistent_error = _("No such user.");
                            continue;
                          }

                        endpwent ();
                      }
                  }

                if (scope == SCOPE_GROUP)
                  {
                    if (strcasecmp (name, "other") != 0)
                      {
                        struct group *gp = getgrnam (name);

                        if (gp == NULL)
                          {
                            if (traditional)
                              {
                                move (LINES - 3, 0);
                                clrtoeol ();
                                mvprintw (LINES - 3, 39, _("--No such group--"));
                              }
                            else
                              persistent_error = _("No such group.");
                            continue;
                          }

                        endgrent ();
                      }
                  }

                node = list_head (&access_list);
                for (i=0; i<entries; i++)
                  {
                    access_entry = (struct access *) list_data (node);
                    if (access_scope (access_entry) == scope &&
                        strcmp (access_name (access_entry), name) == 0)
                      {
                        if (traditional)
                          {
                            move (LINES - 3, 0);
                            clrtoeol ();
                            mvprintw (LINES - 3, 39, _("%s entry exists"), name);
                          }
                        else
                          persistent_error =
                            scope == SCOPE_USER ? _("User already exists in "
                                             "permission table.") :
                            (scope == SCOPE_GROUP ? _("Group already exists in "
                                               "permission table.") :
                             _("System already exists in permission table."));
                        restart = TRUE;
                        continue;
                      }
                    node = list_next (node);
                    if (node == NULL)
                      continue;
                  }

                if (restart)
                  continue;

                {
                  struct access *new_access = access_alloc ();

                  access_set_permissions (new_access, READ | WRITE | REPLY);
                  access_set_scope (new_access, scope);
                  access_set_name (new_access, name);

                  get_mode (new_access, &access_list, first, entries);

                  list_insert_sorted (&access_list, (void *) new_access);
                }

                newts_free (name);

                entries++;
                redraw = TRUE;
                changed = TRUE;
                clear ();
                display_access (&access_list, first, entries);
              }

            if (!traditional)
              redraw = TRUE;
            break;
          }

        case 'd':  /* Delete existing entries. */
          {
            ListNode *node, *prev;
            struct access *data;
            int key, number, i;

            move (LINES - 2, 0);
            clrtoeol ();
            if (traditional)
              printw ("%s", _("Delete entry #: "));
            else
              printw ("%s", _("Delete entry number: "));

            key = getch ();
            while (key != '\n' && key != '\r' && key != KEY_ENTER &&
                   (key < '1' || key > '9'))
              key = getch ();

            if (key == '\n' || key == '\r' || key == KEY_ENTER)
              {
                redraw = TRUE;
                break;
              }

            number = get_number (key, entries);
            if (number < 0)
              {
                redraw = TRUE;
                break;
              }
            if (number > entries || key < '0' || key > '9' || number == 0)
              {
                clear ();
                display_access (&access_list, first, entries);
                if (traditional)
                  {
                    move (LINES - 1, 0);
                    clrtoeol ();
                    printw ("%s", _("Bad entry"));
                  }
                else
                  {
                    move (LINES - 3, 0);
                    clrtoeol ();
                    printw ("%s", _("Invalid entry."));
                  }
                break;
              }

            number--;  /* Adjust to base zero. */

            prev = NULL;
            node = list_head (&access_list);
            for (i=0; i<number; i++)
              {
                prev = node;
                node = list_next (prev);
              }

            data = (struct access *) list_data (node);
            if (data->scope == SCOPE_USER && strcmp (data->name, username) == 0)
              {
                clear ();
                display_access (&access_list, first, entries);
                if (traditional)
                  {
                    move (LINES - 1, 0);
                    clrtoeol ();
                    printw ("%s", _(" Can't Delete self"));
                  }
                else
                  {
                    move (LINES - 3, 0);
                    clrtoeol ();
                    printw ("%s", _("Can't delete own entry."));
                  }
                break;
              }

            list_remove_next (&access_list, prev, NULL);

            entries--;
            changed = TRUE;
            redraw = TRUE;
            break;
          }

        case 'm':  /* Modify existing entries. */
          {
            ListNode *node;
            struct access *existing_entry;
            int key, number, i;

            move (LINES - 2, 0);
            clrtoeol ();
            if (traditional)
              printw ("%s", _("Modify entry #: "));
            else
              printw ("%s", _("Modify entry number: "));

            key = getch ();
            while (key != '\n' && key != '\r' && key != KEY_ENTER &&
                   (key < '1' || key > '9'))
              key = getch ();

            if (key == '\n' || key == '\r' || key == KEY_ENTER)
              {
                redraw = TRUE;
                break;
              }

            number = get_number (key, entries);
            if (number < 0)
              {
                redraw = TRUE;
                break;
              }
            if (number > entries || key < '0' || key > '9' || number == 0)
              {
                clear ();
                display_access (&access_list, first, entries);
                if (traditional)
                  {
                    move (LINES - 1, 0);
                    clrtoeol ();
                    printw ("%s", _("Bad entry"));
                  }
                else
                  {
                    move (LINES - 3, 0);
                    clrtoeol ();
                    printw ("%s", _("Invalid entry."));
                  }
                break;
              }

            number--;  /* Adjust to base zero. */

            node = list_head (&access_list);
            for (i=0; i<number; i++)
              {
                node = list_next (node);
              }

            existing_entry = (struct access *) list_data (node);
            get_mode (existing_entry, &access_list, first, entries);
            changed = TRUE;
            redraw = TRUE;
            break;
          }

        case '\004':
          list_destroy (&access_list);
          return QUITNOSEQ;

        case 'z':
          list_destroy (&access_list);
          return QUITSEQ;

        default:
          beep ();
          break;
        }
    }

  return 0;
}